20 #include <winpr/wtsapi.h>
21 #include <freerdp/config.h>
24 #include "capabilities.h"
27 #include <winpr/crt.h>
28 #include <winpr/rpc.h>
30 #include <freerdp/log.h>
32 #define TAG FREERDP_TAG("core.capabilities")
34 static 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" };
66 static 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
75 static BOOL rdp_print_capability_sets(
wStream* s,
size_t start, BOOL receiving);
80 static const GUID CODEC_GUID_REMOTEFX = {
81 0x76772F12, 0xBD72, 0x4463, { 0xAF, 0xB3, 0xB7, 0x3C, 0x9C, 0x6F, 0x78, 0x86 }
86 static const GUID CODEC_GUID_NSCODEC = {
87 0xCA8D1BB9, 0x000F, 0x154F, { 0x58, 0x9F, 0xAE, 0x2D, 0x1A, 0x87, 0xE2, 0xD6 }
92 static const GUID CODEC_GUID_IGNORE = {
93 0x9C4351A6, 0x3535, 0x42AE, { 0x91, 0x0C, 0xCD, 0xFC, 0xE5, 0x76, 0x0B, 0x58 }
98 static const GUID CODEC_GUID_IMAGE_REMOTEFX = {
99 0x2744CCD4, 0x9D8A, 0x4E74, { 0x80, 0x3C, 0x0E, 0xCB, 0xEE, 0xA1, 0x9C, 0x54 }
102 #if defined(WITH_JPEG)
105 static const GUID CODEC_GUID_JPEG = {
106 0x430C9EED, 0x1BAF, 0x4CE6, { 0x86, 0x9A, 0xCB, 0x8B, 0x37, 0xB6, 0x62, 0x37 }
110 static BOOL rdp_read_capability_set_header(
wStream* s, UINT16* length, UINT16* type)
113 WINPR_ASSERT(length);
116 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
118 Stream_Read_UINT16(s, *type);
119 Stream_Read_UINT16(s, *length);
125 static 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);
133 static size_t rdp_capability_set_start(
wStream* s)
135 size_t header = Stream_GetPosition(s);
136 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), CAPSET_HEADER_LENGTH))
138 Stream_Zero(s, CAPSET_HEADER_LENGTH);
142 static 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);
158 static 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;
200 static BOOL rdp_read_general_capability_set(
wStream* s, rdpSettings* settings)
202 UINT16 extraFlags = 0;
203 BYTE refreshRectSupport = 0;
204 BYTE suppressOutputSupport = 0;
206 if (!Stream_CheckAndLogRequiredLength(TAG, 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)
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)
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;
259 static BOOL rdp_write_general_capability_set(
wStream* s,
const rdpSettings* settings)
261 if (!Stream_EnsureRemainingCapacity(s, 64))
264 const size_t header = rdp_capability_set_start(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))
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)
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
316 static BOOL rdp_print_general_capability_set(
wStream* s)
318 UINT16 osMajorType = 0;
319 UINT16 osMinorType = 0;
320 UINT16 protocolVersion = 0;
321 UINT16 pad2OctetsA = 0;
322 UINT16 generalCompressionTypes = 0;
323 UINT16 extraFlags = 0;
324 UINT16 updateCapabilityFlag = 0;
325 UINT16 remoteUnshareFlag = 0;
326 UINT16 generalCompressionLevel = 0;
327 BYTE refreshRectSupport = 0;
328 BYTE suppressOutputSupport = 0;
330 if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
333 WLog_VRB(TAG,
"GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
334 Stream_Read_UINT16(s, osMajorType);
335 Stream_Read_UINT16(s, osMinorType);
336 Stream_Read_UINT16(s, protocolVersion);
337 Stream_Read_UINT16(s, pad2OctetsA);
338 Stream_Read_UINT16(s, generalCompressionTypes);
339 Stream_Read_UINT16(s, extraFlags);
340 Stream_Read_UINT16(s, updateCapabilityFlag);
341 Stream_Read_UINT16(s, remoteUnshareFlag);
342 Stream_Read_UINT16(s, generalCompressionLevel);
343 Stream_Read_UINT8(s, refreshRectSupport);
344 Stream_Read_UINT8(s, suppressOutputSupport);
345 WLog_VRB(TAG,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
346 WLog_VRB(TAG,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
347 WLog_VRB(TAG,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
348 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
349 WLog_VRB(TAG,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"", generalCompressionTypes);
350 WLog_VRB(TAG,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
351 WLog_VRB(TAG,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
352 WLog_VRB(TAG,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
353 WLog_VRB(TAG,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"", generalCompressionLevel);
354 WLog_VRB(TAG,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
355 WLog_VRB(TAG,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
359 static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
361 WINPR_ASSERT(settings);
364 if (!settings->ServerMode)
371 if (!src->DesktopResize)
372 settings->DesktopResize = FALSE;
374 if (!settings->ServerMode && settings->DesktopResize)
378 settings->DesktopWidth = src->DesktopWidth;
379 settings->DesktopHeight = src->DesktopHeight;
382 if (settings->DrawAllowSkipAlpha)
383 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
385 if (settings->DrawAllowDynamicColorFidelity)
386 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
388 if (settings->DrawAllowColorSubsampling)
389 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
399 static BOOL rdp_read_bitmap_capability_set(
wStream* s, rdpSettings* settings)
401 BYTE drawingFlags = 0;
402 UINT16 desktopWidth = 0;
403 UINT16 desktopHeight = 0;
404 UINT16 desktopResizeFlag = 0;
405 UINT16 preferredBitsPerPixel = 0;
407 if (!Stream_CheckAndLogRequiredLength(TAG, s, 24))
410 Stream_Read_UINT16(s, preferredBitsPerPixel);
411 Stream_Seek_UINT16(s);
412 Stream_Seek_UINT16(s);
413 Stream_Seek_UINT16(s);
414 Stream_Read_UINT16(s, desktopWidth);
415 Stream_Read_UINT16(s, desktopHeight);
416 Stream_Seek_UINT16(s);
417 Stream_Read_UINT16(s, desktopResizeFlag);
418 Stream_Seek_UINT16(s);
419 Stream_Seek_UINT8(s);
420 Stream_Read_UINT8(s, drawingFlags);
421 Stream_Seek_UINT16(s);
422 Stream_Seek_UINT16(s);
426 settings->DesktopResize = desktopResizeFlag;
427 settings->DesktopWidth = desktopWidth;
428 settings->DesktopHeight = desktopHeight;
429 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) ? TRUE : FALSE;
430 settings->DrawAllowDynamicColorFidelity =
431 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) ? TRUE : FALSE;
432 settings->DrawAllowColorSubsampling =
433 (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) ? TRUE : FALSE;
443 static BOOL rdp_write_bitmap_capability_set(
wStream* s,
const rdpSettings* settings)
445 BYTE drawingFlags = 0;
446 UINT16 preferredBitsPerPixel = 0;
448 if (!Stream_EnsureRemainingCapacity(s, 64))
451 const size_t header = rdp_capability_set_start(s);
453 WINPR_ASSERT(settings);
454 if (settings->DrawAllowSkipAlpha)
455 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
457 if (settings->DrawAllowDynamicColorFidelity)
458 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
460 if (settings->DrawAllowColorSubsampling)
461 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
473 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
476 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
479 preferredBitsPerPixel = 8;
481 Stream_Write_UINT16(s, preferredBitsPerPixel);
482 Stream_Write_UINT16(s, 1);
483 Stream_Write_UINT16(s, 1);
484 Stream_Write_UINT16(s, 1);
485 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
486 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
487 Stream_Write_UINT16(s, 0);
488 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
489 Stream_Write_UINT16(s, 1);
490 Stream_Write_UINT8(s, 0);
491 Stream_Write_UINT8(s, drawingFlags);
492 Stream_Write_UINT16(s, 1);
493 Stream_Write_UINT16(s, 0);
494 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
497 #ifdef WITH_DEBUG_CAPABILITIES
498 static BOOL rdp_print_bitmap_capability_set(
wStream* s)
500 UINT16 preferredBitsPerPixel = 0;
501 UINT16 receive1BitPerPixel = 0;
502 UINT16 receive4BitsPerPixel = 0;
503 UINT16 receive8BitsPerPixel = 0;
504 UINT16 desktopWidth = 0;
505 UINT16 desktopHeight = 0;
506 UINT16 pad2Octets = 0;
507 UINT16 desktopResizeFlag = 0;
508 UINT16 bitmapCompressionFlag = 0;
509 BYTE highColorFlags = 0;
510 BYTE drawingFlags = 0;
511 UINT16 multipleRectangleSupport = 0;
512 UINT16 pad2OctetsB = 0;
513 WLog_VRB(TAG,
"BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
515 if (!Stream_CheckAndLogRequiredLength(TAG, s, 24))
518 Stream_Read_UINT16(s, preferredBitsPerPixel);
519 Stream_Read_UINT16(s, receive1BitPerPixel);
520 Stream_Read_UINT16(s, receive4BitsPerPixel);
521 Stream_Read_UINT16(s, receive8BitsPerPixel);
522 Stream_Read_UINT16(s, desktopWidth);
523 Stream_Read_UINT16(s, desktopHeight);
524 Stream_Read_UINT16(s, pad2Octets);
525 Stream_Read_UINT16(s, desktopResizeFlag);
526 Stream_Read_UINT16(s, bitmapCompressionFlag);
527 Stream_Read_UINT8(s, highColorFlags);
528 Stream_Read_UINT8(s, drawingFlags);
529 Stream_Read_UINT16(s, multipleRectangleSupport);
530 Stream_Read_UINT16(s, pad2OctetsB);
531 WLog_VRB(TAG,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
532 WLog_VRB(TAG,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
533 WLog_VRB(TAG,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
534 WLog_VRB(TAG,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
535 WLog_VRB(TAG,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
536 WLog_VRB(TAG,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
537 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
538 WLog_VRB(TAG,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
539 WLog_VRB(TAG,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
540 WLog_VRB(TAG,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
541 WLog_VRB(TAG,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
542 WLog_VRB(TAG,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"", multipleRectangleSupport);
543 WLog_VRB(TAG,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
547 static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
549 WINPR_ASSERT(settings);
552 BOOL BitmapCacheV3Enabled = FALSE;
553 BOOL FrameMarkerCommandEnabled = FALSE;
555 for (
size_t i = 0; i < 32; i++)
557 if (!src->OrderSupport[i])
558 settings->OrderSupport[i] = FALSE;
561 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
563 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
564 BitmapCacheV3Enabled = TRUE;
566 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
567 FrameMarkerCommandEnabled = TRUE;
570 if (BitmapCacheV3Enabled)
572 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
573 settings->BitmapCacheVersion = src->BitmapCacheVersion;
576 settings->BitmapCacheV3Enabled = FALSE;
578 if (FrameMarkerCommandEnabled && !src->FrameMarkerCommandEnabled)
579 settings->FrameMarkerCommandEnabled = FALSE;
589 static BOOL rdp_read_order_capability_set(
wStream* s, rdpSettings* settings)
591 char terminalDescriptor[17] = { 0 };
592 BYTE orderSupport[32] = { 0 };
593 BOOL BitmapCacheV3Enabled = FALSE;
594 BOOL FrameMarkerCommandEnabled = FALSE;
596 WINPR_ASSERT(settings);
597 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
600 Stream_Read(s, terminalDescriptor, 16);
601 Stream_Seek_UINT32(s);
602 Stream_Seek_UINT16(s);
603 Stream_Seek_UINT16(s);
604 Stream_Seek_UINT16(s);
605 Stream_Seek_UINT16(s);
606 Stream_Seek_UINT16(s);
607 Stream_Read_UINT16(s, settings->OrderSupportFlags);
608 Stream_Read(s, orderSupport, 32);
609 Stream_Seek_UINT16(s);
610 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
611 Stream_Seek_UINT32(s);
612 Stream_Seek_UINT32(s);
613 Stream_Seek_UINT16(s);
614 Stream_Seek_UINT16(s);
615 Stream_Read_UINT16(s, settings->TextANSICodePage);
616 Stream_Seek_UINT16(s);
621 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
622 settings->OrderSupport[i] = orderSupport[i];
624 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
626 BitmapCacheV3Enabled =
627 (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) ? TRUE : FALSE;
628 FrameMarkerCommandEnabled =
629 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) ? TRUE : FALSE;
632 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
633 if (BitmapCacheV3Enabled)
634 settings->BitmapCacheVersion = 3;
636 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
646 static BOOL rdp_write_order_capability_set(
wStream* s,
const rdpSettings* settings)
648 char terminalDescriptor[16] = { 0 };
650 WINPR_ASSERT(settings);
651 if (!Stream_EnsureRemainingCapacity(s, 64))
654 const size_t header = rdp_capability_set_start(s);
656 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
657 UINT16 orderFlags = settings->OrderSupportFlags;
659 if (settings->BitmapCacheV3Enabled)
661 orderSupportExFlags |= CACHE_BITMAP_V3_SUPPORT;
662 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
665 if (settings->FrameMarkerCommandEnabled)
667 orderSupportExFlags |= ALTSEC_FRAME_MARKER_SUPPORT;
668 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
674 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
675 strncpy(terminalDescriptor, dsc, len);
677 Stream_Write(s, terminalDescriptor,
678 sizeof(terminalDescriptor));
679 Stream_Write_UINT32(s, 0);
680 Stream_Write_UINT16(s, 1);
681 Stream_Write_UINT16(s, 20);
682 Stream_Write_UINT16(s, 0);
683 Stream_Write_UINT16(s, 1);
684 Stream_Write_UINT16(s, 0);
685 Stream_Write_UINT16(s, orderFlags);
686 Stream_Write(s, settings->OrderSupport, 32);
687 Stream_Write_UINT16(s, 0);
688 Stream_Write_UINT16(s, orderSupportExFlags);
689 Stream_Write_UINT32(s, 0);
690 Stream_Write_UINT32(s, 230400);
691 Stream_Write_UINT16(s, 0);
692 Stream_Write_UINT16(s, 0);
693 Stream_Write_UINT16(s, settings->TextANSICodePage);
694 Stream_Write_UINT16(s, 0);
695 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
698 #ifdef WITH_DEBUG_CAPABILITIES
699 static BOOL rdp_print_order_capability_set(
wStream* s)
701 BYTE terminalDescriptor[16];
702 UINT32 pad4OctetsA = 0;
703 UINT16 desktopSaveXGranularity = 0;
704 UINT16 desktopSaveYGranularity = 0;
705 UINT16 pad2OctetsA = 0;
706 UINT16 maximumOrderLevel = 0;
707 UINT16 numberFonts = 0;
708 UINT16 orderFlags = 0;
709 BYTE orderSupport[32];
710 UINT16 textFlags = 0;
711 UINT16 orderSupportExFlags = 0;
712 UINT32 pad4OctetsB = 0;
713 UINT32 desktopSaveSize = 0;
714 UINT16 pad2OctetsC = 0;
715 UINT16 pad2OctetsD = 0;
716 UINT16 textANSICodePage = 0;
717 UINT16 pad2OctetsE = 0;
718 WLog_VRB(TAG,
"OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
720 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
723 Stream_Read(s, terminalDescriptor, 16);
724 Stream_Read_UINT32(s, pad4OctetsA);
725 Stream_Read_UINT16(s, desktopSaveXGranularity);
726 Stream_Read_UINT16(s, desktopSaveYGranularity);
727 Stream_Read_UINT16(s, pad2OctetsA);
728 Stream_Read_UINT16(s, maximumOrderLevel);
729 Stream_Read_UINT16(s, numberFonts);
730 Stream_Read_UINT16(s, orderFlags);
731 Stream_Read(s, orderSupport, 32);
732 Stream_Read_UINT16(s, textFlags);
733 Stream_Read_UINT16(s, orderSupportExFlags);
734 Stream_Read_UINT32(s, pad4OctetsB);
735 Stream_Read_UINT32(s, desktopSaveSize);
736 Stream_Read_UINT16(s, pad2OctetsC);
737 Stream_Read_UINT16(s, pad2OctetsD);
738 Stream_Read_UINT16(s, textANSICodePage);
739 Stream_Read_UINT16(s, pad2OctetsE);
740 WLog_VRB(TAG,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
741 WLog_VRB(TAG,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"", desktopSaveXGranularity);
742 WLog_VRB(TAG,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"", desktopSaveYGranularity);
743 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
744 WLog_VRB(TAG,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
745 WLog_VRB(TAG,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
746 WLog_VRB(TAG,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
747 WLog_VRB(TAG,
"\torderSupport:");
748 WLog_VRB(TAG,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
749 WLog_VRB(TAG,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
750 WLog_VRB(TAG,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
751 WLog_VRB(TAG,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
752 WLog_VRB(TAG,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
753 WLog_VRB(TAG,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
754 WLog_VRB(TAG,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
755 WLog_VRB(TAG,
"\t\tDRAWNINEGRID: %" PRIu8
"", orderSupport[NEG_DRAWNINEGRID_INDEX]);
756 WLog_VRB(TAG,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
757 WLog_VRB(TAG,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
758 WLog_VRB(TAG,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
759 WLog_VRB(TAG,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
760 WLog_VRB(TAG,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
761 WLog_VRB(TAG,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
762 WLog_VRB(TAG,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
763 WLog_VRB(TAG,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
764 WLog_VRB(TAG,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
765 WLog_VRB(TAG,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
766 WLog_VRB(TAG,
"\t\tMULTIOPAQUERECT: %" PRIu8
"", orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
767 WLog_VRB(TAG,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
768 WLog_VRB(TAG,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
769 WLog_VRB(TAG,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
770 WLog_VRB(TAG,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
771 WLog_VRB(TAG,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
772 WLog_VRB(TAG,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
773 WLog_VRB(TAG,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
774 WLog_VRB(TAG,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
775 WLog_VRB(TAG,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
776 WLog_VRB(TAG,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
777 WLog_VRB(TAG,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
778 WLog_VRB(TAG,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
779 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
780 WLog_VRB(TAG,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
781 WLog_VRB(TAG,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
782 WLog_VRB(TAG,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
783 WLog_VRB(TAG,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
784 WLog_VRB(TAG,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
785 WLog_VRB(TAG,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
786 WLog_VRB(TAG,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
787 WLog_VRB(TAG,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
788 WLog_VRB(TAG,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
793 static BOOL rdp_apply_bitmap_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
795 WINPR_ASSERT(settings);
805 static BOOL rdp_read_bitmap_cache_capability_set(
wStream* s, rdpSettings* settings)
807 WINPR_UNUSED(settings);
808 WINPR_ASSERT(settings);
810 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
813 Stream_Seek_UINT32(s);
814 Stream_Seek_UINT32(s);
815 Stream_Seek_UINT32(s);
816 Stream_Seek_UINT32(s);
817 Stream_Seek_UINT32(s);
818 Stream_Seek_UINT32(s);
819 Stream_Seek_UINT16(s);
820 Stream_Seek_UINT16(s);
821 Stream_Seek_UINT16(s);
822 Stream_Seek_UINT16(s);
823 Stream_Seek_UINT16(s);
824 Stream_Seek_UINT16(s);
833 static BOOL rdp_write_bitmap_cache_capability_set(
wStream* s,
const rdpSettings* settings)
835 if (!Stream_EnsureRemainingCapacity(s, 64))
838 const size_t header = rdp_capability_set_start(s);
840 if (bpp > UINT16_MAX)
842 Stream_Write_UINT32(s, 0);
843 Stream_Write_UINT32(s, 0);
844 Stream_Write_UINT32(s, 0);
845 Stream_Write_UINT32(s, 0);
846 Stream_Write_UINT32(s, 0);
847 Stream_Write_UINT32(s, 0);
848 UINT32 size = bpp * 256;
849 if (size > UINT16_MAX)
851 Stream_Write_UINT16(s, 200);
852 Stream_Write_UINT16(s, (UINT16)size);
854 if (size > UINT16_MAX)
856 Stream_Write_UINT16(s, 600);
857 Stream_Write_UINT16(s, (UINT16)size);
859 if (size > UINT16_MAX)
861 Stream_Write_UINT16(s, 1000);
862 Stream_Write_UINT16(s, (UINT16)size);
863 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
866 #ifdef WITH_DEBUG_CAPABILITIES
867 static BOOL rdp_print_bitmap_cache_capability_set(
wStream* s)
875 UINT16 Cache0Entries = 0;
876 UINT16 Cache0MaximumCellSize = 0;
877 UINT16 Cache1Entries = 0;
878 UINT16 Cache1MaximumCellSize = 0;
879 UINT16 Cache2Entries = 0;
880 UINT16 Cache2MaximumCellSize = 0;
881 WLog_VRB(TAG,
"BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
883 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
886 Stream_Read_UINT32(s, pad1);
887 Stream_Read_UINT32(s, pad2);
888 Stream_Read_UINT32(s, pad3);
889 Stream_Read_UINT32(s, pad4);
890 Stream_Read_UINT32(s, pad5);
891 Stream_Read_UINT32(s, pad6);
892 Stream_Read_UINT16(s, Cache0Entries);
893 Stream_Read_UINT16(s, Cache0MaximumCellSize);
894 Stream_Read_UINT16(s, Cache1Entries);
895 Stream_Read_UINT16(s, Cache1MaximumCellSize);
896 Stream_Read_UINT16(s, Cache2Entries);
897 Stream_Read_UINT16(s, Cache2MaximumCellSize);
898 WLog_VRB(TAG,
"\tpad1: 0x%08" PRIX32
"", pad1);
899 WLog_VRB(TAG,
"\tpad2: 0x%08" PRIX32
"", pad2);
900 WLog_VRB(TAG,
"\tpad3: 0x%08" PRIX32
"", pad3);
901 WLog_VRB(TAG,
"\tpad4: 0x%08" PRIX32
"", pad4);
902 WLog_VRB(TAG,
"\tpad5: 0x%08" PRIX32
"", pad5);
903 WLog_VRB(TAG,
"\tpad6: 0x%08" PRIX32
"", pad6);
904 WLog_VRB(TAG,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
905 WLog_VRB(TAG,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
906 WLog_VRB(TAG,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
907 WLog_VRB(TAG,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
908 WLog_VRB(TAG,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
909 WLog_VRB(TAG,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
914 static BOOL rdp_apply_control_capability_set(rdpSettings* settings,
const rdpSettings* src)
916 WINPR_ASSERT(settings);
927 static BOOL rdp_read_control_capability_set(
wStream* s, rdpSettings* settings)
929 WINPR_UNUSED(settings);
930 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
933 Stream_Seek_UINT16(s);
934 Stream_Seek_UINT16(s);
935 Stream_Seek_UINT16(s);
936 Stream_Seek_UINT16(s);
945 static BOOL rdp_write_control_capability_set(
wStream* s,
const rdpSettings* settings)
947 WINPR_UNUSED(settings);
948 if (!Stream_EnsureRemainingCapacity(s, 32))
951 const size_t header = rdp_capability_set_start(s);
952 Stream_Write_UINT16(s, 0);
953 Stream_Write_UINT16(s, 0);
954 Stream_Write_UINT16(s, 2);
955 Stream_Write_UINT16(s, 2);
956 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
959 #ifdef WITH_DEBUG_CAPABILITIES
960 static BOOL rdp_print_control_capability_set(
wStream* s)
962 UINT16 controlFlags = 0;
963 UINT16 remoteDetachFlag = 0;
964 UINT16 controlInterest = 0;
965 UINT16 detachInterest = 0;
966 WLog_VRB(TAG,
"ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
968 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
971 Stream_Read_UINT16(s, controlFlags);
972 Stream_Read_UINT16(s, remoteDetachFlag);
973 Stream_Read_UINT16(s, controlInterest);
974 Stream_Read_UINT16(s, detachInterest);
975 WLog_VRB(TAG,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
976 WLog_VRB(TAG,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
977 WLog_VRB(TAG,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
978 WLog_VRB(TAG,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
983 static BOOL rdp_apply_window_activation_capability_set(rdpSettings* settings,
984 const rdpSettings* src)
986 WINPR_ASSERT(settings);
997 static BOOL rdp_read_window_activation_capability_set(
wStream* s, rdpSettings* settings)
999 WINPR_UNUSED(settings);
1000 WINPR_ASSERT(settings);
1001 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1004 Stream_Seek_UINT16(s);
1005 Stream_Seek_UINT16(s);
1006 Stream_Seek_UINT16(s);
1007 Stream_Seek_UINT16(s);
1016 static BOOL rdp_write_window_activation_capability_set(
wStream* s,
const rdpSettings* settings)
1018 WINPR_UNUSED(settings);
1019 WINPR_ASSERT(settings);
1020 if (!Stream_EnsureRemainingCapacity(s, 32))
1023 const size_t header = rdp_capability_set_start(s);
1024 Stream_Write_UINT16(s, 0);
1025 Stream_Write_UINT16(s, 0);
1026 Stream_Write_UINT16(s, 0);
1027 Stream_Write_UINT16(s, 0);
1028 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1031 #ifdef WITH_DEBUG_CAPABILITIES
1032 static BOOL rdp_print_window_activation_capability_set(
wStream* s)
1034 UINT16 helpKeyFlag = 0;
1035 UINT16 helpKeyIndexFlag = 0;
1036 UINT16 helpExtendedKeyFlag = 0;
1037 UINT16 windowManagerKeyFlag = 0;
1039 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1041 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1044 Stream_Read_UINT16(s, helpKeyFlag);
1045 Stream_Read_UINT16(s, helpKeyIndexFlag);
1046 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1047 Stream_Read_UINT16(s, windowManagerKeyFlag);
1048 WLog_VRB(TAG,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1049 WLog_VRB(TAG,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1050 WLog_VRB(TAG,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1051 WLog_VRB(TAG,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1056 static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1058 WINPR_ASSERT(settings);
1062 const UINT32 colorPointerCacheSize =
1064 const UINT32 dstPointerCacheSize =
1066 const UINT32 dstColorPointerCacheSize =
1070 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1071 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1075 actualColorPointerCacheSize))
1086 static BOOL rdp_read_pointer_capability_set(
wStream* s, rdpSettings* settings)
1088 UINT16 colorPointerFlag = 0;
1089 UINT16 colorPointerCacheSize = 0;
1090 UINT16 pointerCacheSize = 0;
1092 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1095 Stream_Read_UINT16(s, colorPointerFlag);
1096 Stream_Read_UINT16(s, colorPointerCacheSize);
1098 if (colorPointerFlag == 0)
1100 WLog_WARN(TAG,
"[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1101 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1102 ". Vaue is ignored and always assumed to be TRUE");
1106 if (Stream_GetRemainingLength(s) >= 2)
1107 Stream_Read_UINT16(s, pointerCacheSize);
1109 WINPR_ASSERT(settings);
1110 settings->PointerCacheSize = pointerCacheSize;
1111 settings->ColorPointerCacheSize = colorPointerCacheSize;
1121 static BOOL rdp_write_pointer_capability_set(
wStream* s,
const rdpSettings* settings)
1123 if (!Stream_EnsureRemainingCapacity(s, 32))
1126 const size_t header = rdp_capability_set_start(s);
1127 if (settings->PointerCacheSize > UINT16_MAX)
1129 if (settings->ColorPointerCacheSize > UINT16_MAX)
1132 WINPR_ASSERT(settings);
1133 const UINT32 colorPointerFlag =
1136 Stream_Write_UINT16(s, colorPointerFlag);
1137 Stream_Write_UINT16(
1138 s, (UINT16)settings->ColorPointerCacheSize);
1139 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1141 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1144 #ifdef WITH_DEBUG_CAPABILITIES
1145 static BOOL rdp_print_pointer_capability_set(
wStream* s)
1147 UINT16 colorPointerFlag = 0;
1148 UINT16 colorPointerCacheSize = 0;
1149 UINT16 pointerCacheSize = 0;
1151 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1154 WLog_VRB(TAG,
"PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1155 Stream_Read_UINT16(s, colorPointerFlag);
1156 Stream_Read_UINT16(s, colorPointerCacheSize);
1157 Stream_Read_UINT16(s, pointerCacheSize);
1158 WLog_VRB(TAG,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1159 WLog_VRB(TAG,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1160 WLog_VRB(TAG,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1165 static BOOL rdp_apply_share_capability_set(rdpSettings* settings,
const rdpSettings* src)
1167 WINPR_ASSERT(settings);
1178 static BOOL rdp_read_share_capability_set(
wStream* s, rdpSettings* settings)
1180 WINPR_UNUSED(settings);
1181 WINPR_ASSERT(settings);
1183 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1186 Stream_Seek_UINT16(s);
1187 Stream_Seek_UINT16(s);
1196 static BOOL rdp_write_share_capability_set(
wStream* s,
const rdpSettings* settings)
1198 if (!Stream_EnsureRemainingCapacity(s, 32))
1201 const size_t header = rdp_capability_set_start(s);
1203 WINPR_ASSERT(settings);
1204 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1205 Stream_Write_UINT16(s, nodeId);
1206 Stream_Write_UINT16(s, 0);
1207 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1210 #ifdef WITH_DEBUG_CAPABILITIES
1211 static BOOL rdp_print_share_capability_set(
wStream* s)
1214 UINT16 pad2Octets = 0;
1215 WLog_VRB(TAG,
"ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1217 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1220 Stream_Read_UINT16(s, nodeId);
1221 Stream_Read_UINT16(s, pad2Octets);
1222 WLog_VRB(TAG,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1223 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1228 static BOOL rdp_apply_color_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1230 WINPR_ASSERT(settings);
1240 static BOOL rdp_read_color_cache_capability_set(
wStream* s, rdpSettings* settings)
1242 WINPR_UNUSED(settings);
1243 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1246 Stream_Seek_UINT16(s);
1247 Stream_Seek_UINT16(s);
1256 static BOOL rdp_write_color_cache_capability_set(
wStream* s,
const rdpSettings* settings)
1258 WINPR_UNUSED(settings);
1259 if (!Stream_EnsureRemainingCapacity(s, 32))
1262 const size_t header = rdp_capability_set_start(s);
1263 Stream_Write_UINT16(s, 6);
1264 Stream_Write_UINT16(s, 0);
1265 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1268 #ifdef WITH_DEBUG_CAPABILITIES
1269 static BOOL rdp_print_color_cache_capability_set(
wStream* s)
1271 UINT16 colorTableCacheSize = 0;
1272 UINT16 pad2Octets = 0;
1273 WLog_VRB(TAG,
"ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1275 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1278 Stream_Read_UINT16(s, colorTableCacheSize);
1279 Stream_Read_UINT16(s, pad2Octets);
1280 WLog_VRB(TAG,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1281 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1286 static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1288 WINPR_ASSERT(settings);
1291 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1301 static BOOL rdp_read_sound_capability_set(
wStream* s, rdpSettings* settings)
1303 UINT16 soundFlags = 0;
1305 WINPR_ASSERT(settings);
1306 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1309 Stream_Read_UINT16(s, soundFlags);
1310 Stream_Seek_UINT16(s);
1311 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE;
1320 static BOOL rdp_write_sound_capability_set(
wStream* s,
const rdpSettings* settings)
1322 WINPR_ASSERT(settings);
1323 if (!Stream_EnsureRemainingCapacity(s, 32))
1326 const size_t header = rdp_capability_set_start(s);
1327 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1328 Stream_Write_UINT16(s, soundFlags);
1329 Stream_Write_UINT16(s, 0);
1330 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1333 #ifdef WITH_DEBUG_CAPABILITIES
1334 static BOOL rdp_print_sound_capability_set(
wStream* s)
1336 UINT16 soundFlags = 0;
1337 UINT16 pad2OctetsA = 0;
1338 WLog_VRB(TAG,
"SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1340 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1343 Stream_Read_UINT16(s, soundFlags);
1344 Stream_Read_UINT16(s, pad2OctetsA);
1345 WLog_VRB(TAG,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1346 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1351 static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1353 WINPR_ASSERT(settings);
1356 if (settings->ServerMode)
1358 settings->KeyboardLayout = src->KeyboardLayout;
1359 settings->KeyboardType = src->KeyboardType;
1360 settings->KeyboardSubType = src->KeyboardSubType;
1361 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1367 if (!settings->ServerMode)
1369 settings->FastPathInput = src->FastPathInput;
1375 if (settings->HasHorizontalWheel)
1376 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1384 if (settings->HasExtendedMouseEvent)
1385 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1386 if (settings->HasRelativeMouseEvent)
1387 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1399 static BOOL rdp_read_input_capability_set(
wStream* s, rdpSettings* settings)
1401 UINT16 inputFlags = 0;
1403 WINPR_ASSERT(settings);
1404 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
1407 Stream_Read_UINT16(s, inputFlags);
1408 Stream_Seek_UINT16(s);
1410 Stream_Read_UINT32(s, settings->KeyboardLayout);
1411 Stream_Read_UINT32(s, settings->KeyboardType);
1412 Stream_Read_UINT32(s, settings->KeyboardSubType);
1413 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1416 WCHAR wstr[32] = { 0 };
1417 char str[65] = { 0 };
1423 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1426 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1427 memset(str, 0,
sizeof(str));
1435 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1438 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) ? TRUE : FALSE))
1441 (inputFlags & INPUT_FLAG_UNICODE) ? TRUE : FALSE))
1444 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) ? TRUE : FALSE))
1447 (inputFlags & INPUT_FLAG_MOUSEX) ? TRUE : FALSE))
1450 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) ? TRUE : FALSE))
1461 static BOOL rdp_write_input_capability_set(
wStream* s,
const rdpSettings* settings)
1463 WINPR_ASSERT(settings);
1464 if (!Stream_EnsureRemainingCapacity(s, 128))
1467 const size_t header = rdp_capability_set_start(s);
1468 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1470 if (settings->FastPathInput)
1472 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1473 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1477 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1480 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1483 inputFlags |= INPUT_FLAG_UNICODE;
1486 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1488 if (settings->HasExtendedMouseEvent)
1489 inputFlags |= INPUT_FLAG_MOUSEX;
1491 Stream_Write_UINT16(s, inputFlags);
1492 Stream_Write_UINT16(s, 0);
1493 Stream_Write_UINT32(s, settings->KeyboardLayout);
1494 Stream_Write_UINT32(s, settings->KeyboardType);
1495 Stream_Write_UINT32(s, settings->KeyboardSubType);
1496 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1498 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1501 #ifdef WITH_DEBUG_CAPABILITIES
1502 static BOOL rdp_print_input_capability_set(
wStream* s)
1504 UINT16 inputFlags = 0;
1505 UINT16 pad2OctetsA = 0;
1506 UINT32 keyboardLayout = 0;
1507 UINT32 keyboardType = 0;
1508 UINT32 keyboardSubType = 0;
1509 UINT32 keyboardFunctionKey = 0;
1510 WLog_VRB(TAG,
"InputCapabilitySet (length %" PRIuz
")", Stream_GetRemainingLength(s));
1512 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
1515 Stream_Read_UINT16(s, inputFlags);
1516 Stream_Read_UINT16(s, pad2OctetsA);
1517 Stream_Read_UINT32(s, keyboardLayout);
1518 Stream_Read_UINT32(s, keyboardType);
1519 Stream_Read_UINT32(s, keyboardSubType);
1520 Stream_Read_UINT32(s, keyboardFunctionKey);
1522 WLog_VRB(TAG,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1523 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1524 WLog_VRB(TAG,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1525 WLog_VRB(TAG,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1526 WLog_VRB(TAG,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1527 WLog_VRB(TAG,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1532 static BOOL rdp_apply_font_capability_set(rdpSettings* settings,
const rdpSettings* src)
1534 WINPR_ASSERT(settings);
1544 static BOOL rdp_read_font_capability_set(
wStream* s, rdpSettings* settings)
1546 WINPR_UNUSED(settings);
1547 if (Stream_GetRemainingLength(s) >= 2)
1548 Stream_Seek_UINT16(s);
1550 if (Stream_GetRemainingLength(s) >= 2)
1551 Stream_Seek_UINT16(s);
1561 static BOOL rdp_write_font_capability_set(
wStream* s,
const rdpSettings* settings)
1563 WINPR_UNUSED(settings);
1564 if (!Stream_EnsureRemainingCapacity(s, 32))
1567 const size_t header = rdp_capability_set_start(s);
1568 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1569 Stream_Write_UINT16(s, 0);
1570 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1573 #ifdef WITH_DEBUG_CAPABILITIES
1574 static BOOL rdp_print_font_capability_set(
wStream* s)
1576 UINT16 fontSupportFlags = 0;
1577 UINT16 pad2Octets = 0;
1578 WLog_VRB(TAG,
"FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1580 if (Stream_GetRemainingLength(s) >= 2)
1581 Stream_Read_UINT16(s, fontSupportFlags);
1583 if (Stream_GetRemainingLength(s) >= 2)
1584 Stream_Read_UINT16(s, pad2Octets);
1586 WLog_VRB(TAG,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1587 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1592 static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1594 WINPR_ASSERT(settings);
1598 settings->BrushSupportLevel = src->BrushSupportLevel;
1607 static BOOL rdp_read_brush_capability_set(
wStream* s, rdpSettings* settings)
1609 WINPR_UNUSED(settings);
1610 WINPR_ASSERT(settings);
1612 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1614 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1623 static BOOL rdp_write_brush_capability_set(
wStream* s,
const rdpSettings* settings)
1625 WINPR_ASSERT(settings);
1626 if (!Stream_EnsureRemainingCapacity(s, 32))
1629 const size_t header = rdp_capability_set_start(s);
1630 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1631 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1634 #ifdef WITH_DEBUG_CAPABILITIES
1635 static BOOL rdp_print_brush_capability_set(
wStream* s)
1637 UINT32 brushSupportLevel = 0;
1638 WLog_VRB(TAG,
"BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1640 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1643 Stream_Read_UINT32(s, brushSupportLevel);
1644 WLog_VRB(TAG,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1655 WINPR_ASSERT(cache_definition);
1656 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1657 Stream_Read_UINT16(s,
1658 cache_definition->cacheMaximumCellSize);
1667 WINPR_ASSERT(cache_definition);
1668 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1669 Stream_Write_UINT16(
1670 s, cache_definition->cacheMaximumCellSize);
1673 static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1675 WINPR_ASSERT(settings);
1678 WINPR_ASSERT(src->GlyphCache);
1679 WINPR_ASSERT(settings->GlyphCache);
1680 for (
size_t x = 0; x < 10; x++)
1681 settings->GlyphCache[x] = src->GlyphCache[x];
1683 WINPR_ASSERT(src->FragCache);
1684 WINPR_ASSERT(settings->FragCache);
1685 settings->FragCache[0] = src->FragCache[0];
1686 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1696 static BOOL rdp_read_glyph_cache_capability_set(
wStream* s, rdpSettings* settings)
1698 WINPR_ASSERT(settings);
1699 if (!Stream_CheckAndLogRequiredLength(TAG, s, 48))
1703 for (
size_t x = 0; x < 10; x++)
1704 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1705 rdp_read_cache_definition(s, settings->FragCache);
1706 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1707 Stream_Seek_UINT16(s);
1716 static BOOL rdp_write_glyph_cache_capability_set(
wStream* s,
const rdpSettings* settings)
1718 WINPR_ASSERT(settings);
1719 if (!Stream_EnsureRemainingCapacity(s, 64))
1722 const size_t header = rdp_capability_set_start(s);
1723 if (settings->GlyphSupportLevel > UINT16_MAX)
1726 for (
size_t x = 0; x < 10; x++)
1727 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1728 rdp_write_cache_definition(s, settings->FragCache);
1729 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1730 Stream_Write_UINT16(s, 0);
1731 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1734 #ifdef WITH_DEBUG_CAPABILITIES
1735 static BOOL rdp_print_glyph_cache_capability_set(
wStream* s)
1739 UINT16 glyphSupportLevel = 0;
1740 UINT16 pad2Octets = 0;
1741 WLog_VRB(TAG,
"GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1743 if (!Stream_CheckAndLogRequiredLength(TAG, s, 48))
1747 rdp_read_cache_definition(s, &glyphCache[0]);
1748 rdp_read_cache_definition(s, &glyphCache[1]);
1749 rdp_read_cache_definition(s, &glyphCache[2]);
1750 rdp_read_cache_definition(s, &glyphCache[3]);
1751 rdp_read_cache_definition(s, &glyphCache[4]);
1752 rdp_read_cache_definition(s, &glyphCache[5]);
1753 rdp_read_cache_definition(s, &glyphCache[6]);
1754 rdp_read_cache_definition(s, &glyphCache[7]);
1755 rdp_read_cache_definition(s, &glyphCache[8]);
1756 rdp_read_cache_definition(s, &glyphCache[9]);
1757 rdp_read_cache_definition(s, &fragCache);
1758 Stream_Read_UINT16(s, glyphSupportLevel);
1759 Stream_Read_UINT16(s, pad2Octets);
1760 WLog_VRB(TAG,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1761 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1762 WLog_VRB(TAG,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1763 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1764 WLog_VRB(TAG,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1765 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1766 WLog_VRB(TAG,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1767 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1768 WLog_VRB(TAG,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1769 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1770 WLog_VRB(TAG,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1771 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1772 WLog_VRB(TAG,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1773 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1774 WLog_VRB(TAG,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1775 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1776 WLog_VRB(TAG,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1777 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1778 WLog_VRB(TAG,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1779 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1780 WLog_VRB(TAG,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1781 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1782 WLog_VRB(TAG,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1783 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1788 static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1789 const rdpSettings* src)
1791 WINPR_ASSERT(settings);
1794 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1795 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1796 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1806 static BOOL rdp_read_offscreen_bitmap_cache_capability_set(
wStream* s, rdpSettings* settings)
1808 UINT32 offscreenSupportLevel = 0;
1810 WINPR_ASSERT(settings);
1811 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1814 Stream_Read_UINT32(s, offscreenSupportLevel);
1815 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1816 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1818 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1828 static BOOL rdp_write_offscreen_bitmap_cache_capability_set(
wStream* s,
const rdpSettings* settings)
1830 UINT32 offscreenSupportLevel = 0x00;
1832 WINPR_ASSERT(settings);
1833 if (!Stream_EnsureRemainingCapacity(s, 32))
1836 const size_t header = rdp_capability_set_start(s);
1837 if (settings->OffscreenSupportLevel)
1839 offscreenSupportLevel = 0x01;
1840 Stream_Write_UINT32(s, offscreenSupportLevel);
1841 Stream_Write_UINT16(s, settings->OffscreenCacheSize);
1842 Stream_Write_UINT16(s,
1843 settings->OffscreenCacheEntries);
1848 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1851 #ifdef WITH_DEBUG_CAPABILITIES
1852 static BOOL rdp_print_offscreen_bitmap_cache_capability_set(
wStream* s)
1854 UINT32 offscreenSupportLevel = 0;
1855 UINT16 offscreenCacheSize = 0;
1856 UINT16 offscreenCacheEntries = 0;
1857 WLog_VRB(TAG,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1858 Stream_GetRemainingLength(s));
1860 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1863 Stream_Read_UINT32(s, offscreenSupportLevel);
1864 Stream_Read_UINT16(s, offscreenCacheSize);
1865 Stream_Read_UINT16(s, offscreenCacheEntries);
1866 WLog_VRB(TAG,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1867 WLog_VRB(TAG,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1868 WLog_VRB(TAG,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1873 static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1874 const rdpSettings* src)
1886 static BOOL rdp_read_bitmap_cache_host_support_capability_set(
wStream* s, rdpSettings* settings)
1888 BYTE cacheVersion = 0;
1890 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1893 Stream_Read_UINT8(s, cacheVersion);
1894 Stream_Seek_UINT8(s);
1895 Stream_Seek_UINT16(s);
1898 cacheVersion & BITMAP_CACHE_V2);
1906 static BOOL rdp_write_bitmap_cache_host_support_capability_set(
wStream* s,
1907 const rdpSettings* settings)
1909 UINT8 cacheVersion = 0;
1912 cacheVersion |= BITMAP_CACHE_V2;
1914 if (!Stream_EnsureRemainingCapacity(s, 32))
1917 const size_t header = rdp_capability_set_start(s);
1918 Stream_Write_UINT8(s, cacheVersion);
1919 Stream_Write_UINT8(s, 0);
1920 Stream_Write_UINT16(s, 0);
1921 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1924 #ifdef WITH_DEBUG_CAPABILITIES
1925 static BOOL rdp_print_bitmap_cache_host_support_capability_set(
wStream* s)
1927 BYTE cacheVersion = 0;
1930 WLog_VRB(TAG,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1931 Stream_GetRemainingLength(s));
1933 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1936 Stream_Read_UINT8(s, cacheVersion);
1937 Stream_Read_UINT8(s, pad1);
1938 Stream_Read_UINT16(s, pad2);
1939 WLog_VRB(TAG,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1940 WLog_VRB(TAG,
"\tpad1: 0x%02" PRIX8
"", pad1);
1941 WLog_VRB(TAG,
"\tpad2: 0x%04" PRIX16
"", pad2);
1950 WINPR_ASSERT(cellInfo);
1951 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1958 Stream_Read_UINT32(s, info);
1959 cellInfo->numEntries = (info & 0x7FFFFFFF);
1960 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
1971 WINPR_ASSERT(cellInfo);
1972 info = (cellInfo->numEntries | (cellInfo->persistent << 31));
1973 Stream_Write_UINT32(s, info);
1976 static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
1978 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
1979 FreeRDP_BitmapCachePersistEnabled };
1981 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
1983 const FreeRDP_Settings_Keys_Bool
id = keys[x];
1990 const UINT32 BitmapCacheV2NumCells =
1993 BitmapCacheV2NumCells))
1996 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
1999 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2000 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2014 static BOOL rdp_read_bitmap_cache_v2_capability_set(
wStream* s, rdpSettings* settings)
2016 UINT16 cacheFlags = 0;
2017 WINPR_UNUSED(settings);
2018 WINPR_ASSERT(settings);
2020 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2023 Stream_Read_UINT16(s, cacheFlags);
2028 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2031 Stream_Seek_UINT8(s);
2032 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2033 if (settings->BitmapCacheV2NumCells > 5)
2035 WLog_ERR(TAG,
"Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2036 settings->BitmapCacheV2NumCells);
2040 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2043 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2044 if (!rdp_read_bitmap_cache_cell_info(s, info))
2049 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2051 if (!Stream_SafeSeek(s, 4))
2063 static BOOL rdp_write_bitmap_cache_v2_capability_set(
wStream* s,
const rdpSettings* settings)
2065 WINPR_ASSERT(settings);
2066 if (!Stream_EnsureRemainingCapacity(s, 64))
2069 const size_t header = rdp_capability_set_start(s);
2070 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2074 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2075 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2076 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2077 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2078 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2079 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2082 Stream_Write_UINT16(s, cacheFlags);
2083 Stream_Write_UINT8(s, 0);
2084 Stream_Write_UINT8(s, settings->BitmapCacheV2NumCells);
2085 rdp_write_bitmap_cache_cell_info(
2086 s, &settings->BitmapCacheV2CellInfo[0]);
2087 rdp_write_bitmap_cache_cell_info(
2088 s, &settings->BitmapCacheV2CellInfo[1]);
2089 rdp_write_bitmap_cache_cell_info(
2090 s, &settings->BitmapCacheV2CellInfo[2]);
2091 rdp_write_bitmap_cache_cell_info(
2092 s, &settings->BitmapCacheV2CellInfo[3]);
2093 rdp_write_bitmap_cache_cell_info(
2094 s, &settings->BitmapCacheV2CellInfo[4]);
2096 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2099 #ifdef WITH_DEBUG_CAPABILITIES
2100 static BOOL rdp_print_bitmap_cache_v2_capability_set(
wStream* s)
2103 WLog_VRB(TAG,
"BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2105 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2108 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2109 const UINT8 pad2 = Stream_Get_UINT8(s);
2110 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2112 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2114 if (!rdp_read_bitmap_cache_cell_info(
2115 s, &bitmapCacheV2CellInfo[x]))
2119 if (!Stream_SafeSeek(s, 12))
2122 WLog_VRB(TAG,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2123 WLog_VRB(TAG,
"\tpad2: 0x%02" PRIX8
"", pad2);
2124 WLog_VRB(TAG,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2125 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2129 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
"",
2130 x, info->numEntries, info->persistent);
2136 static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2138 WINPR_ASSERT(settings);
2142 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2143 (src->VCFlags & VCCAPS_COMPR_SC))
2144 settings->VCFlags |= VCCAPS_COMPR_SC;
2146 settings->VCFlags &= ~VCCAPS_COMPR_SC;
2148 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2149 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2150 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2152 settings->VCFlags &= ~VCCAPS_COMPR_CS_8K;
2159 if (!settings->ServerMode)
2161 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2162 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2165 settings->VCChunkSize = src->VCChunkSize;
2177 static BOOL rdp_read_virtual_channel_capability_set(
wStream* s, rdpSettings* settings)
2180 UINT32 VCChunkSize = 0;
2182 WINPR_ASSERT(settings);
2183 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2186 Stream_Read_UINT32(s, flags);
2188 if (Stream_GetRemainingLength(s) >= 4)
2189 Stream_Read_UINT32(s, VCChunkSize);
2191 VCChunkSize = UINT32_MAX;
2193 settings->VCFlags = flags;
2194 settings->VCChunkSize = VCChunkSize;
2204 static BOOL rdp_write_virtual_channel_capability_set(
wStream* s,
const rdpSettings* settings)
2206 WINPR_ASSERT(settings);
2207 if (!Stream_EnsureRemainingCapacity(s, 32))
2210 const size_t header = rdp_capability_set_start(s);
2211 Stream_Write_UINT32(s, settings->VCFlags);
2212 Stream_Write_UINT32(s, settings->VCChunkSize);
2213 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2216 #ifdef WITH_DEBUG_CAPABILITIES
2217 static BOOL rdp_print_virtual_channel_capability_set(
wStream* s)
2220 UINT32 VCChunkSize = 0;
2221 WLog_VRB(TAG,
"VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2223 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2226 Stream_Read_UINT32(s, flags);
2228 if (Stream_GetRemainingLength(s) >= 4)
2229 Stream_Read_UINT32(s, VCChunkSize);
2233 WLog_VRB(TAG,
"\tflags: 0x%08" PRIX32
"", flags);
2234 WLog_VRB(TAG,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2239 static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2240 const rdpSettings* src)
2242 WINPR_ASSERT(settings);
2245 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2246 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2247 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2257 static BOOL rdp_read_draw_nine_grid_cache_capability_set(
wStream* s, rdpSettings* settings)
2259 UINT32 drawNineGridSupportLevel = 0;
2261 WINPR_ASSERT(settings);
2262 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2265 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2266 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2267 Stream_Read_UINT16(s,
2268 settings->DrawNineGridCacheEntries);
2270 settings->DrawNineGridEnabled =
2271 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) ? TRUE
2282 static BOOL rdp_write_draw_nine_grid_cache_capability_set(
wStream* s,
const rdpSettings* settings)
2284 WINPR_ASSERT(settings);
2285 if (!Stream_EnsureRemainingCapacity(s, 32))
2288 const size_t header = rdp_capability_set_start(s);
2289 const UINT32 drawNineGridSupportLevel =
2290 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2291 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2292 Stream_Write_UINT16(s, settings->DrawNineGridCacheSize);
2293 Stream_Write_UINT16(
2294 s, settings->DrawNineGridCacheEntries);
2295 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2298 static void rdp_write_gdiplus_cache_entries(
wStream* s, UINT16 gce, UINT16 bce, UINT16 pce,
2299 UINT16 ice, UINT16 ace)
2301 Stream_Write_UINT16(s, gce);
2302 Stream_Write_UINT16(s, bce);
2303 Stream_Write_UINT16(s, pce);
2304 Stream_Write_UINT16(s, ice);
2305 Stream_Write_UINT16(s, ace);
2308 static void rdp_write_gdiplus_cache_chunk_size(
wStream* s, UINT16 gccs, UINT16 obccs, UINT16 opccs,
2311 Stream_Write_UINT16(s, gccs);
2312 Stream_Write_UINT16(s, obccs);
2313 Stream_Write_UINT16(s, opccs);
2314 Stream_Write_UINT16(s, oiaccs);
2317 static void rdp_write_gdiplus_image_cache_properties(
wStream* s, UINT16 oiccs, UINT16 oicts,
2320 Stream_Write_UINT16(s, oiccs);
2321 Stream_Write_UINT16(s, oicts);
2322 Stream_Write_UINT16(s, oicms);
2325 #ifdef WITH_DEBUG_CAPABILITIES
2326 static BOOL rdp_print_draw_nine_grid_cache_capability_set(
wStream* s)
2328 UINT32 drawNineGridSupportLevel = 0;
2329 UINT16 DrawNineGridCacheSize = 0;
2330 UINT16 DrawNineGridCacheEntries = 0;
2332 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2334 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2337 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2338 Stream_Read_UINT16(s, DrawNineGridCacheSize);
2339 Stream_Read_UINT16(s, DrawNineGridCacheEntries);
2344 static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2345 const rdpSettings* src)
2347 WINPR_ASSERT(settings);
2350 if (src->DrawGdiPlusEnabled)
2351 settings->DrawGdiPlusEnabled = TRUE;
2353 if (src->DrawGdiPlusCacheEnabled)
2354 settings->DrawGdiPlusCacheEnabled = TRUE;
2364 static BOOL rdp_read_draw_gdiplus_cache_capability_set(
wStream* s, rdpSettings* settings)
2366 UINT32 drawGDIPlusSupportLevel = 0;
2367 UINT32 drawGdiplusCacheLevel = 0;
2369 WINPR_ASSERT(settings);
2370 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2373 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2374 Stream_Seek_UINT32(s);
2375 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2380 settings->DrawGdiPlusEnabled =
2381 (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) ? TRUE : FALSE;
2382 settings->DrawGdiPlusCacheEnabled =
2383 (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) ? TRUE : FALSE;
2393 static BOOL rdp_write_draw_gdiplus_cache_capability_set(
wStream* s,
const rdpSettings* settings)
2395 WINPR_ASSERT(settings);
2396 if (!Stream_EnsureRemainingCapacity(s, 64))
2399 const size_t header = rdp_capability_set_start(s);
2400 const UINT32 drawGDIPlusSupportLevel =
2401 (settings->DrawGdiPlusEnabled) ? DRAW_GDIPLUS_SUPPORTED : DRAW_GDIPLUS_DEFAULT;
2402 const UINT32 drawGdiplusCacheLevel = (settings->DrawGdiPlusEnabled)
2403 ? DRAW_GDIPLUS_CACHE_LEVEL_ONE
2404 : DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT;
2405 Stream_Write_UINT32(s, drawGDIPlusSupportLevel);
2406 Stream_Write_UINT32(s, 0);
2407 Stream_Write_UINT32(s, drawGdiplusCacheLevel);
2408 rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, 2);
2409 rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, 64);
2410 rdp_write_gdiplus_image_cache_properties(s, 4096, 256,
2412 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS);
2415 #ifdef WITH_DEBUG_CAPABILITIES
2416 static BOOL rdp_print_draw_gdiplus_cache_capability_set(
wStream* s)
2418 UINT32 drawGdiPlusSupportLevel = 0;
2419 UINT32 GdipVersion = 0;
2420 UINT32 drawGdiplusCacheLevel = 0;
2422 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2424 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2427 Stream_Read_UINT32(s, drawGdiPlusSupportLevel);
2428 Stream_Read_UINT32(s, GdipVersion);
2429 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2437 static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2439 WINPR_ASSERT(settings);
2442 if (settings->RemoteApplicationMode)
2443 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2448 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2449 if (settings->RemoteApplicationMode)
2450 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2452 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2462 static BOOL rdp_read_remote_programs_capability_set(
wStream* s, rdpSettings* settings)
2464 UINT32 railSupportLevel = 0;
2466 WINPR_ASSERT(settings);
2467 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2470 Stream_Read_UINT32(s, railSupportLevel);
2472 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) ? TRUE : FALSE;
2473 settings->RemoteApplicationSupportLevel = railSupportLevel;
2482 static BOOL rdp_write_remote_programs_capability_set(
wStream* s,
const rdpSettings* settings)
2484 WINPR_ASSERT(settings);
2485 if (!Stream_EnsureRemainingCapacity(s, 64))
2488 const size_t header = rdp_capability_set_start(s);
2489 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2491 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2493 if (settings->RemoteAppLanguageBarSupported)
2494 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2497 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2498 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2499 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2500 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2501 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2502 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2504 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2505 Stream_Write_UINT32(s, railSupportLevel);
2506 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2509 #ifdef WITH_DEBUG_CAPABILITIES
2510 static BOOL rdp_print_remote_programs_capability_set(
wStream* s)
2512 UINT32 railSupportLevel = 0;
2513 WLog_VRB(TAG,
"RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2515 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2518 Stream_Read_UINT32(s, railSupportLevel);
2519 WLog_VRB(TAG,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2524 static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2526 WINPR_ASSERT(settings);
2529 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2530 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2531 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2541 static BOOL rdp_read_window_list_capability_set(
wStream* s, rdpSettings* settings)
2543 WINPR_ASSERT(settings);
2544 if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
2547 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2548 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2549 Stream_Read_UINT16(s,
2550 settings->RemoteAppNumIconCacheEntries);
2559 static BOOL rdp_write_window_list_capability_set(
wStream* s,
const rdpSettings* settings)
2561 WINPR_ASSERT(settings);
2562 if (!Stream_EnsureRemainingCapacity(s, 32))
2565 const size_t header = rdp_capability_set_start(s);
2566 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2567 Stream_Write_UINT8(s, settings->RemoteAppNumIconCaches);
2568 Stream_Write_UINT16(s,
2569 settings->RemoteAppNumIconCacheEntries);
2570 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2573 #ifdef WITH_DEBUG_CAPABILITIES
2574 static BOOL rdp_print_window_list_capability_set(
wStream* s)
2576 UINT32 wndSupportLevel = 0;
2577 BYTE numIconCaches = 0;
2578 UINT16 numIconCacheEntries = 0;
2579 WLog_VRB(TAG,
"WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2581 if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
2584 Stream_Read_UINT32(s, wndSupportLevel);
2585 Stream_Read_UINT8(s, numIconCaches);
2586 Stream_Read_UINT16(s, numIconCacheEntries);
2587 WLog_VRB(TAG,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2588 WLog_VRB(TAG,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2589 WLog_VRB(TAG,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2594 static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2595 const rdpSettings* src)
2597 WINPR_ASSERT(settings);
2600 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2609 static BOOL rdp_read_desktop_composition_capability_set(
wStream* s, rdpSettings* settings)
2611 WINPR_UNUSED(settings);
2612 WINPR_ASSERT(settings);
2614 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2617 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2626 static BOOL rdp_write_desktop_composition_capability_set(
wStream* s,
const rdpSettings* settings)
2628 WINPR_ASSERT(settings);
2630 if (!Stream_EnsureRemainingCapacity(s, 32))
2633 const size_t header = rdp_capability_set_start(s);
2634 const UINT16 compDeskSupportLevel =
2635 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2636 Stream_Write_UINT16(s, compDeskSupportLevel);
2637 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2640 #ifdef WITH_DEBUG_CAPABILITIES
2641 static BOOL rdp_print_desktop_composition_capability_set(
wStream* s)
2643 UINT16 compDeskSupportLevel = 0;
2645 "DesktopCompositionCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2647 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2650 Stream_Read_UINT16(s, compDeskSupportLevel);
2651 WLog_VRB(TAG,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2656 static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2657 const rdpSettings* src)
2659 UINT32 multifragMaxRequestSize = 0;
2661 WINPR_ASSERT(settings);
2664 multifragMaxRequestSize = src->MultifragMaxRequestSize;
2666 if (settings->ServerMode)
2676 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2677 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2679 if (settings->RemoteFxCodec)
2686 if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
2692 settings->RemoteFxCodec = FALSE;
2693 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2702 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2712 if (multifragMaxRequestSize > settings->MultifragMaxRequestSize)
2713 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2723 static BOOL rdp_read_multifragment_update_capability_set(
wStream* s, rdpSettings* settings)
2725 UINT32 multifragMaxRequestSize = 0;
2727 WINPR_ASSERT(settings);
2728 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2731 Stream_Read_UINT32(s, multifragMaxRequestSize);
2732 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2742 static BOOL rdp_write_multifragment_update_capability_set(
wStream* s, rdpSettings* settings)
2744 WINPR_ASSERT(settings);
2745 if (settings->ServerMode && settings->MultifragMaxRequestSize == 0)
2758 UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2759 UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2760 settings->MultifragMaxRequestSize = tileNumX * tileNumY * 16384;
2762 settings->MultifragMaxRequestSize += 16384;
2765 if (!Stream_EnsureRemainingCapacity(s, 32))
2767 const size_t header = rdp_capability_set_start(s);
2768 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2769 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2772 #ifdef WITH_DEBUG_CAPABILITIES
2773 static BOOL rdp_print_multifragment_update_capability_set(
wStream* s)
2775 UINT32 maxRequestSize = 0;
2777 "MultifragmentUpdateCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2779 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2782 Stream_Read_UINT32(s, maxRequestSize);
2783 WLog_VRB(TAG,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2788 static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2790 WINPR_ASSERT(settings);
2793 settings->LargePointerFlag = src->LargePointerFlag;
2802 static BOOL rdp_read_large_pointer_capability_set(
wStream* s, rdpSettings* settings)
2804 UINT16 largePointerSupportFlags = 0;
2806 WINPR_ASSERT(settings);
2807 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2810 Stream_Read_UINT16(s, largePointerSupportFlags);
2811 settings->LargePointerFlag &= largePointerSupportFlags;
2812 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2816 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2817 largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384),
2818 largePointerSupportFlags);
2828 static BOOL rdp_write_large_pointer_capability_set(
wStream* s,
const rdpSettings* settings)
2830 WINPR_ASSERT(settings);
2831 if (!Stream_EnsureRemainingCapacity(s, 32))
2834 const size_t header = rdp_capability_set_start(s);
2835 const UINT16 largePointerSupportFlags =
2836 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2837 Stream_Write_UINT16(s, largePointerSupportFlags);
2838 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2841 #ifdef WITH_DEBUG_CAPABILITIES
2842 static BOOL rdp_print_large_pointer_capability_set(
wStream* s)
2844 UINT16 largePointerSupportFlags = 0;
2845 WLog_VRB(TAG,
"LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2847 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2850 Stream_Read_UINT16(s, largePointerSupportFlags);
2851 WLog_VRB(TAG,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"", largePointerSupportFlags);
2856 static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2858 WINPR_ASSERT(settings);
2865 if (src->FastPathOutput)
2867 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2868 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2869 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2873 settings->SurfaceCommandsSupported = 0;
2874 settings->SurfaceCommandsEnabled = FALSE;
2875 settings->SurfaceFrameMarkerEnabled = FALSE;
2886 static BOOL rdp_read_surface_commands_capability_set(
wStream* s, rdpSettings* settings)
2888 UINT32 cmdFlags = 0;
2890 WINPR_ASSERT(settings);
2891 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2894 Stream_Read_UINT32(s, cmdFlags);
2895 Stream_Seek_UINT32(s);
2896 settings->SurfaceCommandsSupported = cmdFlags;
2897 settings->SurfaceCommandsEnabled =
2898 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) ? TRUE : FALSE;
2899 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) ? TRUE : FALSE;
2908 static BOOL rdp_write_surface_commands_capability_set(
wStream* s,
const rdpSettings* settings)
2910 WINPR_ASSERT(settings);
2911 if (!Stream_EnsureRemainingCapacity(s, 32))
2914 const size_t header = rdp_capability_set_start(s);
2918 if (settings->SurfaceFrameMarkerEnabled)
2919 cmdFlags |= SURFCMDS_FRAME_MARKER;
2921 Stream_Write_UINT32(s, cmdFlags);
2922 Stream_Write_UINT32(s, 0);
2923 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
2926 #ifdef WITH_DEBUG_CAPABILITIES
2927 static BOOL rdp_print_surface_commands_capability_set(
wStream* s)
2929 UINT32 cmdFlags = 0;
2930 UINT32 reserved = 0;
2933 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2935 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2938 Stream_Read_UINT32(s, cmdFlags);
2939 Stream_Read_UINT32(s, reserved);
2940 WLog_VRB(TAG,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
2941 WLog_VRB(TAG,
"\treserved: 0x%08" PRIX32
"", reserved);
2945 static void rdp_print_bitmap_codec_guid(
const GUID* guid)
2949 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
2950 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
2951 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2],
2952 guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
2955 static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
2957 RPC_STATUS rpc_status = 0;
2960 if (UuidEqual(guid, &CODEC_GUID_REMOTEFX, &rpc_status))
2961 return "CODEC_GUID_REMOTEFX";
2962 else if (UuidEqual(guid, &CODEC_GUID_NSCODEC, &rpc_status))
2963 return "CODEC_GUID_NSCODEC";
2964 else if (UuidEqual(guid, &CODEC_GUID_IGNORE, &rpc_status))
2965 return "CODEC_GUID_IGNORE";
2966 else if (UuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX, &rpc_status))
2967 return "CODEC_GUID_IMAGE_REMOTEFX";
2969 #if defined(WITH_JPEG)
2970 else if (UuidEqual(guid, &CODEC_GUID_JPEG, &rpc_status))
2971 return "CODEC_GUID_JPEG";
2974 return "CODEC_GUID_UNKNOWN";
2978 static BOOL rdp_read_bitmap_codec_guid(
wStream* s, GUID* guid)
2983 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16))
2985 Stream_Read(s, g, 16);
2986 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (g[1] << 8U) | g[0];
2987 guid->Data2 = (g[5] << 8U) | g[4];
2988 guid->Data3 = (g[7] << 8U) | g[6];
2989 guid->Data4[0] = g[8];
2990 guid->Data4[1] = g[9];
2991 guid->Data4[2] = g[10];
2992 guid->Data4[3] = g[11];
2993 guid->Data4[4] = g[12];
2994 guid->Data4[5] = g[13];
2995 guid->Data4[6] = g[14];
2996 guid->Data4[7] = g[15];
3000 static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3004 g[0] = guid->Data1 & 0xFF;
3005 g[1] = (guid->Data1 >> 8) & 0xFF;
3006 g[2] = (guid->Data1 >> 16) & 0xFF;
3007 g[3] = (guid->Data1 >> 24) & 0xFF;
3008 g[4] = (guid->Data2) & 0xFF;
3009 g[5] = (guid->Data2 >> 8) & 0xFF;
3010 g[6] = (guid->Data3) & 0xFF;
3011 g[7] = (guid->Data3 >> 8) & 0xFF;
3012 g[8] = guid->Data4[0];
3013 g[9] = guid->Data4[1];
3014 g[10] = guid->Data4[2];
3015 g[11] = guid->Data4[3];
3016 g[12] = guid->Data4[4];
3017 g[13] = guid->Data4[5];
3018 g[14] = guid->Data4[6];
3019 g[15] = guid->Data4[7];
3020 Stream_Write(s, g, 16);
3023 static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3025 WINPR_ASSERT(settings);
3028 if (settings->ServerMode)
3031 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3032 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3033 settings->RemoteFxOnly = src->RemoteFxOnly;
3034 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3035 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3036 settings->NSCodecId = src->NSCodecId;
3037 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3038 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3039 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3042 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3043 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3045 settings->NSCodec && src->NSCodec))
3047 settings->JpegCodec = src->JpegCodec;
3052 static BOOL rdp_read_codec_ts_rfx_icap(
wStream* sub, rdpSettings* settings, UINT16 icapLen)
3055 UINT16 tileSize = 0;
3056 BYTE codecFlags = 0;
3057 BYTE colConvBits = 0;
3058 BYTE transformBits = 0;
3059 BYTE entropyBits = 0;
3064 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3065 " unsupported, expecting size %" PRIu16
" not supported",
3070 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8))
3073 Stream_Read_UINT16(sub, version);
3074 Stream_Read_UINT16(sub, tileSize);
3075 Stream_Read_UINT8(sub, codecFlags);
3076 Stream_Read_UINT8(sub, colConvBits);
3077 Stream_Read_UINT8(sub, transformBits);
3078 Stream_Read_UINT8(sub, entropyBits);
3080 if (version == 0x0009)
3083 if (tileSize != 0x0080)
3086 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" tile size %" PRIu16
3092 else if (version == 0x0100)
3095 if (tileSize != 0x0040)
3098 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" tile size %" PRIu16
3106 WLog_ERR(TAG,
"[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3112 if (colConvBits != 1)
3115 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3116 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3122 if (transformBits != 1)
3125 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3126 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3131 const UINT8 CODEC_MODE = 0x02;
3135 if ((codecFlags & CODEC_MODE) != 0)
3140 else if ((codecFlags & ~CODEC_MODE) != 0)
3142 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3144 (codecFlags & ~CODEC_MODE));
3146 switch (entropyBits)
3148 case CLW_ENTROPY_RLGR1:
3152 case CLW_ENTROPY_RLGR3:
3158 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3159 "unsupported value 0x%02" PRIx8
3160 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3168 static BOOL rdp_read_codec_ts_rfx_capset(
wStream* s, rdpSettings* settings)
3170 UINT16 blockType = 0;
3171 UINT32 blockLen = 0;
3172 BYTE rfxCodecId = 0;
3173 UINT16 capsetType = 0;
3174 UINT16 numIcaps = 0;
3177 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
3181 Stream_Read_UINT16(s, blockType);
3182 Stream_Read_UINT32(s, blockLen);
3183 if (blockType != 0xCBC1)
3186 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3187 "] != CBY_CAPSET (0xCBC1)",
3191 if (blockLen < 6ull)
3193 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu16
"] < 6", blockLen);
3196 if (!Stream_CheckAndLogRequiredLength(TAG, s, blockLen - 6ull))
3200 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3203 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 7))
3206 Stream_Read_UINT8(sub, rfxCodecId);
3207 Stream_Read_UINT16(sub, capsetType);
3208 Stream_Read_UINT16(sub, numIcaps);
3209 Stream_Read_UINT16(sub, icapLen);
3211 if (rfxCodecId != 1)
3213 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1",
3218 if (capsetType != 0xCFC0)
3221 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3222 "] != CLY_CAPSET (0xCFC0)",
3229 if (!rdp_read_codec_ts_rfx_icap(sub, settings, icapLen))
3235 static BOOL rdp_read_codec_ts_rfx_caps(
wStream* sub, rdpSettings* settings)
3237 if (Stream_GetRemainingLength(sub) == 0)
3240 UINT16 blockType = 0;
3241 UINT32 blockLen = 0;
3242 UINT16 numCapsets = 0;
3245 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8))
3247 Stream_Read_UINT16(sub, blockType);
3248 Stream_Read_UINT32(sub, blockLen);
3249 Stream_Read_UINT16(sub, numCapsets);
3251 if (blockType != 0xCBC0)
3254 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3255 "] != CBY_CAPS (0xCBC0)",
3262 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8", blockLen);
3266 if (numCapsets != 1)
3268 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[" PRIu16
"] != 1",
3273 for (UINT16 x = 0; x < numCapsets; x++)
3275 if (!rdp_read_codec_ts_rfx_capset(sub, settings))
3282 static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(
wStream* s, rdpSettings* settings)
3284 UINT32 rfxCapsLength = 0;
3285 UINT32 rfxPropsLength = 0;
3286 UINT32 captureFlags = 0;
3289 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3291 Stream_Read_UINT32(s, rfxPropsLength);
3292 if (rfxPropsLength < 4)
3295 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3296 " too short, require at least 4 bytes",
3300 if (!Stream_CheckAndLogRequiredLength(TAG, s, rfxPropsLength - 4ull))
3304 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3307 Stream_Seek(s, rfxPropsLength - 4ull);
3309 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8))
3312 Stream_Read_UINT32(sub, captureFlags);
3313 Stream_Read_UINT32(sub, rfxCapsLength);
3314 if (!Stream_CheckAndLogRequiredLength(TAG, sub, rfxCapsLength))
3317 settings->RemoteFxCaptureFlags = captureFlags;
3318 settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? FALSE : TRUE;
3322 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3323 WINPR_ASSERT(ts_sub);
3324 return rdp_read_codec_ts_rfx_caps(ts_sub, settings);
3332 static BOOL rdp_read_bitmap_codecs_capability_set(
wStream* s, rdpSettings* settings, BOOL isServer)
3335 GUID codecGuid = { 0 };
3336 RPC_STATUS rpc_status = 0;
3337 BYTE bitmapCodecCount = 0;
3338 UINT16 codecPropertiesLength = 0;
3340 BOOL guidNSCodec = FALSE;
3341 BOOL guidRemoteFx = FALSE;
3342 BOOL guidRemoteFxImage = FALSE;
3344 WINPR_ASSERT(settings);
3345 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3348 Stream_Read_UINT8(s, bitmapCodecCount);
3350 while (bitmapCodecCount > 0)
3354 if (!rdp_read_bitmap_codec_guid(s, &codecGuid))
3356 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
3358 Stream_Read_UINT8(s, codecId);
3359 Stream_Read_UINT16(s, codecPropertiesLength);
3361 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3362 if (!Stream_SafeSeek(s, codecPropertiesLength))
3367 if (UuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX, &rpc_status))
3369 guidRemoteFx = TRUE;
3370 settings->RemoteFxCodecId = codecId;
3371 if (!rdp_read_codec_ts_rfx_clnt_caps_container(sub, settings))
3374 else if (UuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX, &rpc_status))
3377 guidRemoteFxImage = TRUE;
3378 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3381 else if (UuidEqual(&codecGuid, &CODEC_GUID_NSCODEC, &rpc_status))
3383 BYTE colorLossLevel = 0;
3384 BYTE fAllowSubsampling = 0;
3385 BYTE fAllowDynamicFidelity = 0;
3387 settings->NSCodecId = codecId;
3388 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 3))
3390 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3391 Stream_Read_UINT8(sub, fAllowSubsampling);
3392 Stream_Read_UINT8(sub, colorLossLevel);
3394 if (colorLossLevel < 1)
3397 if (colorLossLevel > 7)
3400 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3401 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3402 settings->NSCodecColorLossLevel = colorLossLevel;
3404 else if (UuidEqual(&codecGuid, &CODEC_GUID_IGNORE, &rpc_status))
3406 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3411 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3417 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3421 const size_t rest = Stream_GetRemainingLength(sub);
3425 "error while reading codec properties: actual size: %" PRIuz
3426 " expected size: %" PRIu32
"",
3427 rest + codecPropertiesLength, codecPropertiesLength);
3448 static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3450 UINT32 captureFlags = 0;
3453 WINPR_ASSERT(settings);
3454 if (!Stream_EnsureRemainingCapacity(s, 64))
3457 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3458 codecMode = settings->RemoteFxCodecMode;
3459 Stream_Write_UINT16(s, 49);
3461 Stream_Write_UINT32(s, 49);
3462 Stream_Write_UINT32(s, captureFlags);
3463 Stream_Write_UINT32(s, 37);
3465 Stream_Write_UINT16(s, CBY_CAPS);
3466 Stream_Write_UINT32(s, 8);
3467 Stream_Write_UINT16(s, 1);
3469 Stream_Write_UINT16(s, CBY_CAPSET);
3470 Stream_Write_UINT32(s, 29);
3471 Stream_Write_UINT8(s, 0x01);
3472 Stream_Write_UINT16(s, CLY_CAPSET);
3473 Stream_Write_UINT16(s, 2);
3474 Stream_Write_UINT16(s, 8);
3476 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3477 Stream_Write_UINT16(s, CT_TILE_64x64);
3478 Stream_Write_UINT8(s, codecMode);
3479 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3480 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3481 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3483 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3484 Stream_Write_UINT16(s, CT_TILE_64x64);
3485 Stream_Write_UINT8(s, codecMode);
3486 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3487 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3488 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3495 static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3497 WINPR_ASSERT(settings);
3499 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3500 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3501 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3503 if (colorLossLevel < 1)
3506 if (colorLossLevel > 7)
3509 if (!Stream_EnsureRemainingCapacity(s, 8))
3512 Stream_Write_UINT16(s, 3);
3514 Stream_Write_UINT8(s,
3515 fAllowDynamicFidelity ? TRUE : FALSE);
3516 Stream_Write_UINT8(s, fAllowSubsampling ? TRUE : FALSE);
3517 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3521 #if defined(WITH_JPEG)
3522 static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3524 WINPR_ASSERT(settings);
3525 if (!Stream_EnsureRemainingCapacity(s, 8))
3528 Stream_Write_UINT16(s, 1);
3529 Stream_Write_UINT8(s, settings->JpegQuality);
3537 static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3539 WINPR_UNUSED(settings);
3540 WINPR_ASSERT(settings);
3542 if (!Stream_EnsureRemainingCapacity(s, 8))
3545 Stream_Write_UINT16(s, 4);
3546 Stream_Write_UINT32(s, 0);
3550 static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3552 WINPR_UNUSED(settings);
3553 WINPR_ASSERT(settings);
3555 if (!Stream_EnsureRemainingCapacity(s, 8))
3558 Stream_Write_UINT16(s, 1);
3559 Stream_Write_UINT8(s, 75);
3566 static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3568 WINPR_UNUSED(settings);
3569 WINPR_ASSERT(settings);
3571 if (!Stream_EnsureRemainingCapacity(s, 8))
3574 Stream_Write_UINT16(s, 4);
3575 Stream_Write_UINT32(s, 0);
3584 static BOOL rdp_write_bitmap_codecs_capability_set(
wStream* s,
const rdpSettings* settings)
3586 WINPR_ASSERT(settings);
3587 if (!Stream_EnsureRemainingCapacity(s, 64))
3590 const size_t header = rdp_capability_set_start(s);
3591 BYTE bitmapCodecCount = 0;
3593 if (settings->RemoteFxCodec)
3599 #if defined(WITH_JPEG)
3601 if (settings->JpegCodec)
3606 if (settings->RemoteFxImageCodec)
3609 Stream_Write_UINT8(s, bitmapCodecCount);
3611 if (settings->RemoteFxCodec)
3613 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3615 if (settings->ServerMode)
3617 Stream_Write_UINT8(s, 0);
3619 if (!rdp_write_rfx_server_capability_container(s, settings))
3624 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3626 if (!rdp_write_rfx_client_capability_container(s, settings))
3633 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3635 if (settings->ServerMode)
3637 Stream_Write_UINT8(s, 0);
3639 if (!rdp_write_nsc_server_capability_container(s, settings))
3644 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3646 if (!rdp_write_nsc_client_capability_container(s, settings))
3651 #if defined(WITH_JPEG)
3653 if (settings->JpegCodec)
3655 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3657 if (settings->ServerMode)
3659 Stream_Write_UINT8(s, 0);
3661 if (!rdp_write_jpeg_server_capability_container(s, settings))
3666 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3668 if (!rdp_write_jpeg_client_capability_container(s, settings))
3675 if (settings->RemoteFxImageCodec)
3677 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3679 if (settings->ServerMode)
3681 Stream_Write_UINT8(s, 0);
3683 if (!rdp_write_rfx_server_capability_container(s, settings))
3688 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3690 if (!rdp_write_rfx_client_capability_container(s, settings))
3695 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3698 #ifdef WITH_DEBUG_CAPABILITIES
3699 static BOOL rdp_print_bitmap_codecs_capability_set(
wStream* s)
3701 GUID codecGuid = { 0 };
3702 BYTE bitmapCodecCount = 0;
3704 UINT16 codecPropertiesLength = 0;
3706 WLog_VRB(TAG,
"BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3708 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3711 Stream_Read_UINT8(s, bitmapCodecCount);
3712 WLog_VRB(TAG,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3714 while (bitmapCodecCount > 0)
3716 if (!rdp_read_bitmap_codec_guid(s, &codecGuid))
3718 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
3720 Stream_Read_UINT8(s, codecId);
3721 WLog_VRB(TAG,
"\tcodecGuid: 0x");
3722 rdp_print_bitmap_codec_guid(&codecGuid);
3723 WLog_VRB(TAG,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3724 WLog_VRB(TAG,
"\tcodecId: %" PRIu8
"", codecId);
3725 Stream_Read_UINT16(s, codecPropertiesLength);
3726 WLog_VRB(TAG,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3728 if (!Stream_SafeSeek(s, codecPropertiesLength))
3737 static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3738 const rdpSettings* src)
3740 WINPR_ASSERT(settings);
3743 if (settings->ServerMode)
3744 settings->FrameAcknowledge = src->FrameAcknowledge;
3753 static BOOL rdp_read_frame_acknowledge_capability_set(
wStream* s, rdpSettings* settings)
3755 WINPR_ASSERT(settings);
3756 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3759 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3768 static BOOL rdp_write_frame_acknowledge_capability_set(
wStream* s,
const rdpSettings* settings)
3770 WINPR_ASSERT(settings);
3771 if (!Stream_EnsureRemainingCapacity(s, 32))
3774 const size_t header = rdp_capability_set_start(s);
3775 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3776 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3779 #ifdef WITH_DEBUG_CAPABILITIES
3780 static BOOL rdp_print_frame_acknowledge_capability_set(
wStream* s)
3782 UINT32 frameAcknowledge = 0;
3784 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3786 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3789 Stream_Read_UINT32(s, frameAcknowledge);
3790 WLog_VRB(TAG,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3795 static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3796 const rdpSettings* src)
3798 WINPR_ASSERT(settings);
3801 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3805 static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(
wStream* s, rdpSettings* settings)
3807 BYTE bitmapCacheV3CodecId = 0;
3809 WINPR_ASSERT(settings);
3810 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3813 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3814 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3818 static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(
wStream* s,
3819 const rdpSettings* settings)
3821 WINPR_ASSERT(settings);
3822 if (!Stream_EnsureRemainingCapacity(s, 32))
3825 const size_t header = rdp_capability_set_start(s);
3826 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3828 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3829 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3832 #ifdef WITH_DEBUG_CAPABILITIES
3833 static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(
wStream* s)
3835 BYTE bitmapCacheV3CodecId = 0;
3836 WLog_VRB(TAG,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3837 Stream_GetRemainingLength(s));
3839 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3842 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3843 WLog_VRB(TAG,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3847 BOOL rdp_print_capability_sets(
wStream* s,
size_t start, BOOL receiving)
3852 UINT16 numberCapabilities = 0;
3854 size_t pos = Stream_GetPosition(s);
3856 Stream_SetPosition(s, start);
3859 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3864 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 4))
3868 Stream_Read_UINT16(s, numberCapabilities);
3871 while (numberCapabilities > 0)
3877 if (!rdp_read_capability_set_header(s, &length, &type))
3880 WLog_VRB(TAG,
"%s ", receiving ?
"Receiving" :
"Sending");
3881 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
3882 if (!Stream_SafeSeek(s, length - 4))
3887 case CAPSET_TYPE_GENERAL:
3888 if (!rdp_print_general_capability_set(sub))
3893 case CAPSET_TYPE_BITMAP:
3894 if (!rdp_print_bitmap_capability_set(sub))
3899 case CAPSET_TYPE_ORDER:
3900 if (!rdp_print_order_capability_set(sub))
3905 case CAPSET_TYPE_BITMAP_CACHE:
3906 if (!rdp_print_bitmap_cache_capability_set(sub))
3911 case CAPSET_TYPE_CONTROL:
3912 if (!rdp_print_control_capability_set(sub))
3917 case CAPSET_TYPE_ACTIVATION:
3918 if (!rdp_print_window_activation_capability_set(sub))
3923 case CAPSET_TYPE_POINTER:
3924 if (!rdp_print_pointer_capability_set(sub))
3929 case CAPSET_TYPE_SHARE:
3930 if (!rdp_print_share_capability_set(sub))
3935 case CAPSET_TYPE_COLOR_CACHE:
3936 if (!rdp_print_color_cache_capability_set(sub))
3941 case CAPSET_TYPE_SOUND:
3942 if (!rdp_print_sound_capability_set(sub))
3947 case CAPSET_TYPE_INPUT:
3948 if (!rdp_print_input_capability_set(sub))
3953 case CAPSET_TYPE_FONT:
3954 if (!rdp_print_font_capability_set(sub))
3959 case CAPSET_TYPE_BRUSH:
3960 if (!rdp_print_brush_capability_set(sub))
3965 case CAPSET_TYPE_GLYPH_CACHE:
3966 if (!rdp_print_glyph_cache_capability_set(sub))
3971 case CAPSET_TYPE_OFFSCREEN_CACHE:
3972 if (!rdp_print_offscreen_bitmap_cache_capability_set(sub))
3977 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
3978 if (!rdp_print_bitmap_cache_host_support_capability_set(sub))
3983 case CAPSET_TYPE_BITMAP_CACHE_V2:
3984 if (!rdp_print_bitmap_cache_v2_capability_set(sub))
3989 case CAPSET_TYPE_VIRTUAL_CHANNEL:
3990 if (!rdp_print_virtual_channel_capability_set(sub))
3995 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
3996 if (!rdp_print_draw_nine_grid_cache_capability_set(sub))
4001 case CAPSET_TYPE_DRAW_GDI_PLUS:
4002 if (!rdp_print_draw_gdiplus_cache_capability_set(sub))
4007 case CAPSET_TYPE_RAIL:
4008 if (!rdp_print_remote_programs_capability_set(sub))
4013 case CAPSET_TYPE_WINDOW:
4014 if (!rdp_print_window_list_capability_set(sub))
4019 case CAPSET_TYPE_COMP_DESK:
4020 if (!rdp_print_desktop_composition_capability_set(sub))
4025 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4026 if (!rdp_print_multifragment_update_capability_set(sub))
4031 case CAPSET_TYPE_LARGE_POINTER:
4032 if (!rdp_print_large_pointer_capability_set(sub))
4037 case CAPSET_TYPE_SURFACE_COMMANDS:
4038 if (!rdp_print_surface_commands_capability_set(sub))
4043 case CAPSET_TYPE_BITMAP_CODECS:
4044 if (!rdp_print_bitmap_codecs_capability_set(sub))
4049 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4050 if (!rdp_print_frame_acknowledge_capability_set(sub))
4055 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4056 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(sub))
4062 WLog_ERR(TAG,
"unknown capability type %" PRIu16
"", type);
4066 rest = Stream_GetRemainingLength(sub);
4070 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4071 " bytes expected, %" PRIuz
"bytes remaining",
4072 type, length, rest);
4075 numberCapabilities--;
4080 Stream_SetPosition(s, pos);
4085 static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4089 case CAPSET_TYPE_GENERAL:
4090 return rdp_apply_general_capability_set(dst, src);
4091 case CAPSET_TYPE_BITMAP:
4092 return rdp_apply_bitmap_capability_set(dst, src);
4093 case CAPSET_TYPE_ORDER:
4094 return rdp_apply_order_capability_set(dst, src);
4095 case CAPSET_TYPE_POINTER:
4096 return rdp_apply_pointer_capability_set(dst, src);
4097 case CAPSET_TYPE_INPUT:
4098 return rdp_apply_input_capability_set(dst, src);
4099 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4100 return rdp_apply_virtual_channel_capability_set(dst, src);
4101 case CAPSET_TYPE_SHARE:
4102 return rdp_apply_share_capability_set(dst, src);
4103 case CAPSET_TYPE_COLOR_CACHE:
4104 return rdp_apply_color_cache_capability_set(dst, src);
4105 case CAPSET_TYPE_FONT:
4106 return rdp_apply_font_capability_set(dst, src);
4107 case CAPSET_TYPE_DRAW_GDI_PLUS:
4108 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4109 case CAPSET_TYPE_RAIL:
4110 return rdp_apply_remote_programs_capability_set(dst, src);
4111 case CAPSET_TYPE_WINDOW:
4112 return rdp_apply_window_list_capability_set(dst, src);
4113 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4114 return rdp_apply_multifragment_update_capability_set(dst, src);
4115 case CAPSET_TYPE_LARGE_POINTER:
4116 return rdp_apply_large_pointer_capability_set(dst, src);
4117 case CAPSET_TYPE_COMP_DESK:
4118 return rdp_apply_desktop_composition_capability_set(dst, src);
4119 case CAPSET_TYPE_SURFACE_COMMANDS:
4120 return rdp_apply_surface_commands_capability_set(dst, src);
4121 case CAPSET_TYPE_BITMAP_CODECS:
4122 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4123 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4124 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4125 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4126 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4127 case CAPSET_TYPE_BITMAP_CACHE:
4128 return rdp_apply_bitmap_cache_capability_set(dst, src);
4129 case CAPSET_TYPE_BITMAP_CACHE_V2:
4130 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4131 case CAPSET_TYPE_BRUSH:
4132 return rdp_apply_brush_capability_set(dst, src);
4133 case CAPSET_TYPE_GLYPH_CACHE:
4134 return rdp_apply_glyph_cache_capability_set(dst, src);
4135 case CAPSET_TYPE_OFFSCREEN_CACHE:
4136 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4137 case CAPSET_TYPE_SOUND:
4138 return rdp_apply_sound_capability_set(dst, src);
4139 case CAPSET_TYPE_CONTROL:
4140 return rdp_apply_control_capability_set(dst, src);
4141 case CAPSET_TYPE_ACTIVATION:
4142 return rdp_apply_window_activation_capability_set(dst, src);
4143 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4144 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4145 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4146 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4152 BOOL rdp_read_capability_set(
wStream* sub, UINT16 type, rdpSettings* settings, BOOL isServer)
4154 WINPR_ASSERT(settings);
4156 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4158 const size_t size = Stream_Length(sub);
4159 if (size > UINT32_MAX)
4162 WINPR_ASSERT(settings->ReceivedCapabilities);
4163 settings->ReceivedCapabilities[type] = TRUE;
4165 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4166 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4168 WINPR_ASSERT(settings->ReceivedCapabilityData);
4169 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4170 if (!tmp && (size > 0))
4172 memcpy(tmp, Stream_Buffer(sub), size);
4173 settings->ReceivedCapabilityData[type] = tmp;
4176 WLog_WARN(TAG,
"not handling capability type %" PRIu16
" yet", type);
4178 BOOL treated = TRUE;
4182 case CAPSET_TYPE_GENERAL:
4183 if (!rdp_read_general_capability_set(sub, settings))
4188 case CAPSET_TYPE_BITMAP:
4189 if (!rdp_read_bitmap_capability_set(sub, settings))
4194 case CAPSET_TYPE_ORDER:
4195 if (!rdp_read_order_capability_set(sub, settings))
4200 case CAPSET_TYPE_POINTER:
4201 if (!rdp_read_pointer_capability_set(sub, settings))
4206 case CAPSET_TYPE_INPUT:
4207 if (!rdp_read_input_capability_set(sub, settings))
4212 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4213 if (!rdp_read_virtual_channel_capability_set(sub, settings))
4218 case CAPSET_TYPE_SHARE:
4219 if (!rdp_read_share_capability_set(sub, settings))
4224 case CAPSET_TYPE_COLOR_CACHE:
4225 if (!rdp_read_color_cache_capability_set(sub, settings))
4230 case CAPSET_TYPE_FONT:
4231 if (!rdp_read_font_capability_set(sub, settings))
4236 case CAPSET_TYPE_DRAW_GDI_PLUS:
4237 if (!rdp_read_draw_gdiplus_cache_capability_set(sub, settings))
4242 case CAPSET_TYPE_RAIL:
4243 if (!rdp_read_remote_programs_capability_set(sub, settings))
4248 case CAPSET_TYPE_WINDOW:
4249 if (!rdp_read_window_list_capability_set(sub, settings))
4254 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4255 if (!rdp_read_multifragment_update_capability_set(sub, settings))
4260 case CAPSET_TYPE_LARGE_POINTER:
4261 if (!rdp_read_large_pointer_capability_set(sub, settings))
4266 case CAPSET_TYPE_COMP_DESK:
4267 if (!rdp_read_desktop_composition_capability_set(sub, settings))
4272 case CAPSET_TYPE_SURFACE_COMMANDS:
4273 if (!rdp_read_surface_commands_capability_set(sub, settings))
4278 case CAPSET_TYPE_BITMAP_CODECS:
4279 if (!rdp_read_bitmap_codecs_capability_set(sub, settings, isServer))
4284 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4285 if (!rdp_read_frame_acknowledge_capability_set(sub, settings))
4290 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4291 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(sub, settings))
4308 case CAPSET_TYPE_BITMAP_CACHE:
4309 if (!rdp_read_bitmap_cache_capability_set(sub, settings))
4314 case CAPSET_TYPE_BITMAP_CACHE_V2:
4315 if (!rdp_read_bitmap_cache_v2_capability_set(sub, settings))
4320 case CAPSET_TYPE_BRUSH:
4321 if (!rdp_read_brush_capability_set(sub, settings))
4326 case CAPSET_TYPE_GLYPH_CACHE:
4327 if (!rdp_read_glyph_cache_capability_set(sub, settings))
4332 case CAPSET_TYPE_OFFSCREEN_CACHE:
4333 if (!rdp_read_offscreen_bitmap_cache_capability_set(sub, settings))
4338 case CAPSET_TYPE_SOUND:
4339 if (!rdp_read_sound_capability_set(sub, settings))
4344 case CAPSET_TYPE_CONTROL:
4345 if (!rdp_read_control_capability_set(sub, settings))
4350 case CAPSET_TYPE_ACTIVATION:
4351 if (!rdp_read_window_activation_capability_set(sub, settings))
4356 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4357 if (!rdp_read_draw_nine_grid_cache_capability_set(sub, settings))
4363 WLog_ERR(TAG,
"capability %s(%" PRIu16
") not expected from client",
4364 get_capability_name(type), type);
4373 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4374 if (!rdp_read_bitmap_cache_host_support_capability_set(sub, settings))
4380 WLog_ERR(TAG,
"capability %s(%" PRIu16
") not expected from server",
4381 get_capability_name(type), type);
4387 const size_t rest = Stream_GetRemainingLength(sub);
4390 const size_t length = Stream_Capacity(sub);
4392 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4393 type, length - rest, length);
4398 static BOOL rdp_read_capability_sets(
wStream* s, rdpSettings* settings, rdpSettings* rcvSettings,
4405 UINT16 numberCapabilities = 0;
4408 #ifdef WITH_DEBUG_CAPABILITIES
4409 const size_t capstart = Stream_GetPosition(s);
4413 WINPR_ASSERT(settings);
4415 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
4418 Stream_Read_UINT16(s, numberCapabilities);
4420 count = numberCapabilities;
4422 start = Stream_GetPosition(s);
4423 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4430 if (!rdp_read_capability_set_header(s, &length, &type))
4432 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4433 if (!Stream_SafeSeek(s, length - 4))
4436 if (!rdp_read_capability_set(sub, type, rcvSettings, settings->ServerMode))
4439 if (!rdp_apply_from_received(type, settings, rcvSettings))
4441 numberCapabilities--;
4444 end = Stream_GetPosition(s);
4447 if (numberCapabilities)
4450 "strange we haven't read the number of announced capacity sets, read=%d "
4451 "expected=%" PRIu16
"",
4452 count - numberCapabilities, count);
4455 #ifdef WITH_DEBUG_CAPABILITIES
4456 rdp_print_capability_sets(s, capstart, TRUE);
4459 if (len > totalLength)
4461 WLog_ERR(TAG,
"Capability length expected %" PRIu16
", actual %" PRIdz, totalLength, len);
4464 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4469 BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4472 WINPR_ASSERT(rdp->context);
4474 if (!rdp_read_header(rdp, s, length, pChannelId))
4477 if (freerdp_shall_disconnect_context(rdp->context))
4480 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4482 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4484 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4486 WLog_ERR(TAG,
"unexpected MCS channel id %04" PRIx16
" received", *pChannelId);
4494 BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4496 UINT16 lengthSourceDescriptor = 0;
4497 UINT16 lengthCombinedCapabilities = 0;
4500 WINPR_ASSERT(rdp->settings);
4501 WINPR_ASSERT(rdp->context);
4504 rdp->settings->PduSource = pduSource;
4506 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
4509 Stream_Read_UINT32(s, rdp->settings->ShareId);
4510 Stream_Read_UINT16(s, lengthSourceDescriptor);
4511 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4513 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4514 !Stream_CheckAndLogRequiredLength(TAG, s, 4))
4518 if (!rdp_read_capability_sets(s, rdp->settings, rdp->remoteSettings,
4519 lengthCombinedCapabilities))
4521 WLog_ERR(TAG,
"rdp_read_capability_sets failed");
4525 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
4528 UINT32 SessionId = 0;
4529 Stream_Read_UINT32(s, SessionId);
4533 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4536 return tpkt_ensure_stream_consumed(s, length);
4539 static BOOL rdp_write_demand_active(
wStream* s, rdpSettings* settings)
4544 UINT16 numberCapabilities = 0;
4545 size_t lengthCombinedCapabilities = 0;
4547 if (!Stream_EnsureRemainingCapacity(s, 64))
4550 Stream_Write_UINT32(s, settings->ShareId);
4551 Stream_Write_UINT16(s, 4);
4552 lm = Stream_GetPosition(s);
4553 Stream_Seek_UINT16(s);
4554 Stream_Write(s,
"RDP", 4);
4555 bm = Stream_GetPosition(s);
4556 Stream_Seek_UINT16(s);
4557 Stream_Write_UINT16(s, 0);
4558 numberCapabilities = 14;
4560 if (!rdp_write_general_capability_set(s, settings) ||
4561 !rdp_write_bitmap_capability_set(s, settings) ||
4562 !rdp_write_order_capability_set(s, settings) ||
4563 !rdp_write_pointer_capability_set(s, settings) ||
4564 !rdp_write_input_capability_set(s, settings) ||
4565 !rdp_write_virtual_channel_capability_set(s, settings) ||
4566 !rdp_write_share_capability_set(s, settings) ||
4567 !rdp_write_font_capability_set(s, settings) ||
4568 !rdp_write_multifragment_update_capability_set(s, settings) ||
4569 !rdp_write_large_pointer_capability_set(s, settings) ||
4570 !rdp_write_desktop_composition_capability_set(s, settings) ||
4571 !rdp_write_surface_commands_capability_set(s, settings) ||
4572 !rdp_write_bitmap_codecs_capability_set(s, settings) ||
4573 !rdp_write_frame_acknowledge_capability_set(s, settings))
4580 numberCapabilities++;
4582 if (!rdp_write_bitmap_cache_host_support_capability_set(s, settings))
4586 if (settings->RemoteApplicationMode)
4588 numberCapabilities += 2;
4590 if (!rdp_write_remote_programs_capability_set(s, settings) ||
4591 !rdp_write_window_list_capability_set(s, settings))
4595 em = Stream_GetPosition(s);
4596 Stream_SetPosition(s, lm);
4597 lengthCombinedCapabilities = (em - bm);
4598 if (lengthCombinedCapabilities > UINT16_MAX)
4600 Stream_Write_UINT16(
4601 s, (UINT16)lengthCombinedCapabilities);
4602 Stream_SetPosition(s, bm);
4603 Stream_Write_UINT16(s, numberCapabilities);
4604 #ifdef WITH_DEBUG_CAPABILITIES
4605 rdp_print_capability_sets(s, bm, FALSE);
4607 Stream_SetPosition(s, em);
4608 Stream_Write_UINT32(s, 0);
4612 BOOL rdp_send_demand_active(rdpRdp* rdp)
4614 wStream* s = rdp_send_stream_pdu_init(rdp);
4620 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4621 status = rdp_write_demand_active(s, rdp->settings) &&
4622 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId);
4627 BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4629 rdpSettings* settings = NULL;
4630 UINT16 lengthSourceDescriptor = 0;
4631 UINT16 lengthCombinedCapabilities = 0;
4635 settings = rdp->settings;
4636 WINPR_ASSERT(settings);
4638 if (!Stream_CheckAndLogRequiredLength(TAG, s, 10))
4641 Stream_Seek_UINT32(s);
4642 Stream_Seek_UINT16(s);
4643 Stream_Read_UINT16(s, lengthSourceDescriptor);
4644 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4646 if (!Stream_CheckAndLogRequiredLength(TAG, s, lengthSourceDescriptor + 4U))
4649 Stream_Seek(s, lengthSourceDescriptor);
4650 if (!rdp_read_capability_sets(s, rdp->settings, rdp->remoteSettings,
4651 lengthCombinedCapabilities))
4654 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4657 settings->SurfaceCommandsEnabled = FALSE;
4658 settings->SurfaceFrameMarkerEnabled = FALSE;
4661 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4664 settings->FrameAcknowledge = 0;
4667 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4670 settings->BitmapCacheV3Enabled = FALSE;
4673 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4684 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4687 settings->MultifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
4690 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4693 settings->LargePointerFlag = 0;
4696 return tpkt_ensure_stream_consumed(s, pduLength);
4699 static BOOL rdp_write_confirm_active(
wStream* s, rdpSettings* settings)
4704 UINT16 numberCapabilities = 0;
4705 UINT16 lengthSourceDescriptor = 0;
4706 size_t lengthCombinedCapabilities = 0;
4709 WINPR_ASSERT(settings);
4711 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4712 Stream_Write_UINT32(s, settings->ShareId);
4713 Stream_Write_UINT16(s, 0x03EA);
4714 Stream_Write_UINT16(s, lengthSourceDescriptor);
4715 lm = Stream_GetPosition(s);
4716 Stream_Seek_UINT16(s);
4717 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4718 bm = Stream_GetPosition(s);
4719 Stream_Seek_UINT16(s);
4720 Stream_Write_UINT16(s, 0);
4722 numberCapabilities = 15;
4724 if (!rdp_write_general_capability_set(s, settings) ||
4725 !rdp_write_bitmap_capability_set(s, settings) ||
4726 !rdp_write_order_capability_set(s, settings))
4729 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4730 ret = rdp_write_bitmap_cache_v2_capability_set(s, settings);
4732 ret = rdp_write_bitmap_cache_capability_set(s, settings);
4737 if (!rdp_write_pointer_capability_set(s, settings) ||
4738 !rdp_write_input_capability_set(s, settings) ||
4739 !rdp_write_brush_capability_set(s, settings) ||
4740 !rdp_write_glyph_cache_capability_set(s, settings) ||
4741 !rdp_write_virtual_channel_capability_set(s, settings) ||
4742 !rdp_write_sound_capability_set(s, settings) ||
4743 !rdp_write_share_capability_set(s, settings) ||
4744 !rdp_write_font_capability_set(s, settings) ||
4745 !rdp_write_control_capability_set(s, settings) ||
4746 !rdp_write_color_cache_capability_set(s, settings) ||
4747 !rdp_write_window_activation_capability_set(s, settings))
4752 if (settings->OffscreenSupportLevel)
4754 numberCapabilities++;
4756 if (!rdp_write_offscreen_bitmap_cache_capability_set(s, settings))
4760 if (settings->DrawNineGridEnabled)
4762 numberCapabilities++;
4764 if (!rdp_write_draw_nine_grid_cache_capability_set(s, settings))
4768 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4770 if (settings->LargePointerFlag)
4772 numberCapabilities++;
4774 if (!rdp_write_large_pointer_capability_set(s, settings))
4779 if (settings->RemoteApplicationMode)
4781 numberCapabilities += 2;
4783 if (!rdp_write_remote_programs_capability_set(s, settings) ||
4784 !rdp_write_window_list_capability_set(s, settings))
4788 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4790 numberCapabilities++;
4792 if (!rdp_write_multifragment_update_capability_set(s, settings))
4796 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4798 numberCapabilities++;
4800 if (!rdp_write_surface_commands_capability_set(s, settings))
4804 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4806 numberCapabilities++;
4808 if (!rdp_write_bitmap_codecs_capability_set(s, settings))
4812 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4813 settings->FrameAcknowledge = 0;
4815 if (settings->FrameAcknowledge)
4817 numberCapabilities++;
4819 if (!rdp_write_frame_acknowledge_capability_set(s, settings))
4823 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4825 if (settings->BitmapCacheV3CodecId != 0)
4827 numberCapabilities++;
4829 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(s, settings))
4834 em = Stream_GetPosition(s);
4835 Stream_SetPosition(s, lm);
4836 lengthCombinedCapabilities = (em - bm);
4837 if (lengthCombinedCapabilities > UINT16_MAX)
4839 Stream_Write_UINT16(
4840 s, (UINT16)lengthCombinedCapabilities);
4841 Stream_SetPosition(s, bm);
4842 Stream_Write_UINT16(s, numberCapabilities);
4843 #ifdef WITH_DEBUG_CAPABILITIES
4844 rdp_print_capability_sets(s, bm, FALSE);
4846 Stream_SetPosition(s, em);
4851 BOOL rdp_send_confirm_active(rdpRdp* rdp)
4853 wStream* s = rdp_send_stream_pdu_init(rdp);
4859 status = rdp_write_confirm_active(s, rdp->settings) &&
4860 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId);
4865 const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
4867 char prefix[16] = { 0 };
4869 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
4870 winpr_str_append(prefix, buffer, len,
"");
4871 if ((flags & INPUT_FLAG_SCANCODES) != 0)
4872 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
4873 if ((flags & INPUT_FLAG_MOUSEX) != 0)
4874 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
4875 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
4876 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
4877 if ((flags & INPUT_FLAG_UNICODE) != 0)
4878 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
4879 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
4880 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
4881 if ((flags & INPUT_FLAG_UNUSED1) != 0)
4882 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
4883 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
4884 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
4885 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
4886 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
4887 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
4888 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
4889 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 const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
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 BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.