20 #include <winpr/wtsapi.h>
21 #include <winpr/assert.h>
22 #include <winpr/cast.h>
23 #include <freerdp/config.h>
26 #include "capabilities.h"
29 #include <winpr/crt.h>
30 #include <winpr/rpc.h>
32 #include <freerdp/log.h>
34 #define TAG FREERDP_TAG("core.capabilities")
36 static const char*
const CAPSET_TYPE_STRINGS[] = {
"Unknown",
53 "Offscreen Bitmap Cache",
54 "Bitmap Cache Host Support",
61 "Desktop Composition",
62 "Multifragment Update",
66 "Frame Acknowledge" };
68 static const char* get_capability_name(UINT16 type)
70 if (type > CAPSET_TYPE_FRAME_ACKNOWLEDGE)
73 return CAPSET_TYPE_STRINGS[type];
76 #ifdef WITH_DEBUG_CAPABILITIES
77 static BOOL rdp_print_capability_sets(
wStream* s,
size_t start, BOOL receiving);
82 static const GUID CODEC_GUID_REMOTEFX = {
83 0x76772F12, 0xBD72, 0x4463, { 0xAF, 0xB3, 0xB7, 0x3C, 0x9C, 0x6F, 0x78, 0x86 }
88 static const GUID CODEC_GUID_NSCODEC = {
89 0xCA8D1BB9, 0x000F, 0x154F, { 0x58, 0x9F, 0xAE, 0x2D, 0x1A, 0x87, 0xE2, 0xD6 }
94 static const GUID CODEC_GUID_IGNORE = {
95 0x9C4351A6, 0x3535, 0x42AE, { 0x91, 0x0C, 0xCD, 0xFC, 0xE5, 0x76, 0x0B, 0x58 }
100 static const GUID CODEC_GUID_IMAGE_REMOTEFX = {
101 0x2744CCD4, 0x9D8A, 0x4E74, { 0x80, 0x3C, 0x0E, 0xCB, 0xEE, 0xA1, 0x9C, 0x54 }
104 #if defined(WITH_JPEG)
107 static const GUID CODEC_GUID_JPEG = {
108 0x430C9EED, 0x1BAF, 0x4CE6, { 0x86, 0x9A, 0xCB, 0x8B, 0x37, 0xB6, 0x62, 0x37 }
112 static BOOL rdp_read_capability_set_header(
wStream* s, UINT16* length, UINT16* type)
115 WINPR_ASSERT(length);
118 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
120 Stream_Read_UINT16(s, *type);
121 Stream_Read_UINT16(s, *length);
127 static void rdp_write_capability_set_header(
wStream* s, UINT16 length, UINT16 type)
130 WINPR_ASSERT(Stream_GetRemainingCapacity(s) >= 4);
131 Stream_Write_UINT16(s, type);
132 Stream_Write_UINT16(s, length);
135 static size_t rdp_capability_set_start(
wStream* s)
137 size_t header = Stream_GetPosition(s);
138 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), CAPSET_HEADER_LENGTH))
140 Stream_Zero(s, CAPSET_HEADER_LENGTH);
144 static BOOL rdp_capability_set_finish(
wStream* s,
size_t header, UINT16 type)
146 const size_t footer = Stream_GetPosition(s);
149 if (header > UINT16_MAX)
151 const size_t length = footer - header;
152 if ((Stream_Capacity(s) < header + 4ULL) || (length > UINT16_MAX))
154 Stream_SetPosition(s, header);
155 rdp_write_capability_set_header(s, (UINT16)length, type);
156 Stream_SetPosition(s, footer);
160 static BOOL rdp_apply_general_capability_set(rdpSettings* settings,
const rdpSettings* src)
162 WINPR_ASSERT(settings);
165 if (settings->ServerMode)
167 settings->OsMajorType = src->OsMajorType;
168 settings->OsMinorType = src->OsMinorType;
171 settings->CapsProtocolVersion = src->CapsProtocolVersion;
172 settings->NoBitmapCompressionHeader = src->NoBitmapCompressionHeader;
173 settings->LongCredentialsSupported = src->LongCredentialsSupported;
174 settings->AutoReconnectionPacketSupported = src->AutoReconnectionPacketSupported;
175 if (!src->FastPathOutput)
176 settings->FastPathOutput = FALSE;
178 if (!src->SaltedChecksum)
179 settings->SaltedChecksum = FALSE;
181 if (!settings->ServerMode)
188 if (!src->RefreshRect)
189 settings->RefreshRect = FALSE;
191 if (!src->SuppressOutput)
192 settings->SuppressOutput = FALSE;
202 static BOOL rdp_read_general_capability_set(
wStream* s, rdpSettings* settings)
204 UINT16 extraFlags = 0;
205 BYTE refreshRectSupport = 0;
206 BYTE suppressOutputSupport = 0;
208 if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
211 WINPR_ASSERT(settings);
212 Stream_Read_UINT16(s, settings->OsMajorType);
213 Stream_Read_UINT16(s, settings->OsMinorType);
215 Stream_Read_UINT16(s, settings->CapsProtocolVersion);
216 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
219 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
220 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
221 settings->CapsProtocolVersion, TS_CAPS_PROTOCOLVERSION);
222 if (settings->CapsProtocolVersion == 0x0000)
225 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
226 " assuming old FreeRDP, ignoring protocol violation, correcting value.",
227 settings->CapsProtocolVersion);
228 settings->CapsProtocolVersion = TS_CAPS_PROTOCOLVERSION;
233 Stream_Seek_UINT16(s);
235 s, settings->CapsGeneralCompressionTypes);
236 Stream_Read_UINT16(s, extraFlags);
237 Stream_Read_UINT16(s, settings->CapsUpdateCapabilityFlag);
238 Stream_Read_UINT16(s, settings->CapsRemoteUnshareFlag);
240 s, settings->CapsGeneralCompressionLevel);
241 Stream_Read_UINT8(s, refreshRectSupport);
242 Stream_Read_UINT8(s, suppressOutputSupport);
243 settings->NoBitmapCompressionHeader = (extraFlags & NO_BITMAP_COMPRESSION_HDR) ? TRUE : FALSE;
244 settings->LongCredentialsSupported = (extraFlags & LONG_CREDENTIALS_SUPPORTED) ? TRUE : FALSE;
246 settings->AutoReconnectionPacketSupported =
247 (extraFlags & AUTORECONNECT_SUPPORTED) ? TRUE : FALSE;
248 settings->FastPathOutput = (extraFlags & FASTPATH_OUTPUT_SUPPORTED) ? TRUE : FALSE;
249 settings->SaltedChecksum = (extraFlags & ENC_SALTED_CHECKSUM) ? TRUE : FALSE;
250 settings->RefreshRect = refreshRectSupport;
251 settings->SuppressOutput = suppressOutputSupport;
261 static BOOL rdp_write_general_capability_set(
wStream* s,
const rdpSettings* settings)
263 if (!Stream_EnsureRemainingCapacity(s, 64))
266 const size_t header = rdp_capability_set_start(s);
267 UINT16 extraFlags = 0;
269 WINPR_ASSERT(settings);
270 if (settings->LongCredentialsSupported)
271 extraFlags |= LONG_CREDENTIALS_SUPPORTED;
273 if (settings->NoBitmapCompressionHeader)
274 extraFlags |= NO_BITMAP_COMPRESSION_HDR;
276 if (settings->AutoReconnectionPacketSupported)
277 extraFlags |= AUTORECONNECT_SUPPORTED;
279 if (settings->FastPathOutput)
280 extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
282 if (settings->SaltedChecksum)
283 extraFlags |= ENC_SALTED_CHECKSUM;
285 if ((settings->OsMajorType > UINT16_MAX) || (settings->OsMinorType > UINT16_MAX))
288 "OsMajorType=%08" PRIx32
", OsMinorType=%08" PRIx32
289 " they need to be smaller %04" PRIx16,
290 settings->OsMajorType, settings->OsMinorType, UINT16_MAX);
293 if (settings->CapsProtocolVersion != TS_CAPS_PROTOCOLVERSION)
296 "TS_GENERAL_CAPABILITYSET::protocolVersion(0x%04" PRIx16
297 ") != TS_CAPS_PROTOCOLVERSION(0x%04" PRIx32
")",
298 settings->CapsProtocolVersion, TS_CAPS_PROTOCOLVERSION);
301 Stream_Write_UINT16(s, (UINT16)settings->OsMajorType);
302 Stream_Write_UINT16(s, (UINT16)settings->OsMinorType);
303 Stream_Write_UINT16(s, settings->CapsProtocolVersion);
304 Stream_Write_UINT16(s, 0);
306 s, settings->CapsGeneralCompressionTypes);
307 Stream_Write_UINT16(s, extraFlags);
308 Stream_Write_UINT16(s, settings->CapsUpdateCapabilityFlag);
309 Stream_Write_UINT16(s, settings->CapsRemoteUnshareFlag);
311 s, settings->CapsGeneralCompressionLevel);
312 Stream_Write_UINT8(s, settings->RefreshRect ? 1 : 0);
313 Stream_Write_UINT8(s, settings->SuppressOutput ? 1 : 0);
314 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GENERAL);
317 #ifdef WITH_DEBUG_CAPABILITIES
318 static BOOL rdp_print_general_capability_set(
wStream* s)
320 UINT16 osMajorType = 0;
321 UINT16 osMinorType = 0;
322 UINT16 protocolVersion = 0;
323 UINT16 pad2OctetsA = 0;
324 UINT16 generalCompressionTypes = 0;
325 UINT16 extraFlags = 0;
326 UINT16 updateCapabilityFlag = 0;
327 UINT16 remoteUnshareFlag = 0;
328 UINT16 generalCompressionLevel = 0;
329 BYTE refreshRectSupport = 0;
330 BYTE suppressOutputSupport = 0;
332 if (!Stream_CheckAndLogRequiredLength(TAG, s, 20))
335 WLog_VRB(TAG,
"GeneralCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
336 Stream_Read_UINT16(s, osMajorType);
337 Stream_Read_UINT16(s, osMinorType);
338 Stream_Read_UINT16(s, protocolVersion);
339 Stream_Read_UINT16(s, pad2OctetsA);
340 Stream_Read_UINT16(s, generalCompressionTypes);
341 Stream_Read_UINT16(s, extraFlags);
342 Stream_Read_UINT16(s, updateCapabilityFlag);
343 Stream_Read_UINT16(s, remoteUnshareFlag);
344 Stream_Read_UINT16(s, generalCompressionLevel);
345 Stream_Read_UINT8(s, refreshRectSupport);
346 Stream_Read_UINT8(s, suppressOutputSupport);
347 WLog_VRB(TAG,
"\tosMajorType: 0x%04" PRIX16
"", osMajorType);
348 WLog_VRB(TAG,
"\tosMinorType: 0x%04" PRIX16
"", osMinorType);
349 WLog_VRB(TAG,
"\tprotocolVersion: 0x%04" PRIX16
"", protocolVersion);
350 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
351 WLog_VRB(TAG,
"\tgeneralCompressionTypes: 0x%04" PRIX16
"", generalCompressionTypes);
352 WLog_VRB(TAG,
"\textraFlags: 0x%04" PRIX16
"", extraFlags);
353 WLog_VRB(TAG,
"\tupdateCapabilityFlag: 0x%04" PRIX16
"", updateCapabilityFlag);
354 WLog_VRB(TAG,
"\tremoteUnshareFlag: 0x%04" PRIX16
"", remoteUnshareFlag);
355 WLog_VRB(TAG,
"\tgeneralCompressionLevel: 0x%04" PRIX16
"", generalCompressionLevel);
356 WLog_VRB(TAG,
"\trefreshRectSupport: 0x%02" PRIX8
"", refreshRectSupport);
357 WLog_VRB(TAG,
"\tsuppressOutputSupport: 0x%02" PRIX8
"", suppressOutputSupport);
361 static BOOL rdp_apply_bitmap_capability_set(rdpSettings* settings,
const rdpSettings* src)
363 WINPR_ASSERT(settings);
366 if (!settings->ServerMode)
373 if (!src->DesktopResize)
374 settings->DesktopResize = FALSE;
376 if (!settings->ServerMode && settings->DesktopResize)
380 settings->DesktopWidth = src->DesktopWidth;
381 settings->DesktopHeight = src->DesktopHeight;
384 if (settings->DrawAllowSkipAlpha)
385 settings->DrawAllowSkipAlpha = src->DrawAllowSkipAlpha;
387 if (settings->DrawAllowDynamicColorFidelity)
388 settings->DrawAllowDynamicColorFidelity = src->DrawAllowDynamicColorFidelity;
390 if (settings->DrawAllowColorSubsampling)
391 settings->DrawAllowColorSubsampling = src->DrawAllowColorSubsampling;
401 static BOOL rdp_read_bitmap_capability_set(
wStream* s, rdpSettings* settings)
403 BYTE drawingFlags = 0;
404 UINT16 desktopWidth = 0;
405 UINT16 desktopHeight = 0;
406 UINT16 desktopResizeFlag = 0;
407 UINT16 preferredBitsPerPixel = 0;
409 if (!Stream_CheckAndLogRequiredLength(TAG, s, 24))
412 Stream_Read_UINT16(s, preferredBitsPerPixel);
413 Stream_Seek_UINT16(s);
414 Stream_Seek_UINT16(s);
415 Stream_Seek_UINT16(s);
416 Stream_Read_UINT16(s, desktopWidth);
417 Stream_Read_UINT16(s, desktopHeight);
418 Stream_Seek_UINT16(s);
419 Stream_Read_UINT16(s, desktopResizeFlag);
420 Stream_Seek_UINT16(s);
421 Stream_Seek_UINT8(s);
422 Stream_Read_UINT8(s, drawingFlags);
423 Stream_Seek_UINT16(s);
424 Stream_Seek_UINT16(s);
428 settings->DesktopResize = desktopResizeFlag;
429 settings->DesktopWidth = desktopWidth;
430 settings->DesktopHeight = desktopHeight;
431 settings->DrawAllowSkipAlpha = (drawingFlags & DRAW_ALLOW_SKIP_ALPHA) ? TRUE : FALSE;
432 settings->DrawAllowDynamicColorFidelity =
433 (drawingFlags & DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY) ? TRUE : FALSE;
434 settings->DrawAllowColorSubsampling =
435 (drawingFlags & DRAW_ALLOW_COLOR_SUBSAMPLING) ? TRUE : FALSE;
445 static BOOL rdp_write_bitmap_capability_set(
wStream* s,
const rdpSettings* settings)
447 BYTE drawingFlags = 0;
448 UINT16 preferredBitsPerPixel = 0;
450 if (!Stream_EnsureRemainingCapacity(s, 64))
453 const size_t header = rdp_capability_set_start(s);
455 WINPR_ASSERT(settings);
456 if (settings->DrawAllowSkipAlpha)
457 drawingFlags |= DRAW_ALLOW_SKIP_ALPHA;
459 if (settings->DrawAllowDynamicColorFidelity)
460 drawingFlags |= DRAW_ALLOW_DYNAMIC_COLOR_FIDELITY;
462 if (settings->DrawAllowColorSubsampling)
463 drawingFlags |= DRAW_ALLOW_COLOR_SUBSAMPLING;
475 (settings->DesktopWidth > UINT16_MAX) || (settings->DesktopHeight > UINT16_MAX))
478 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
481 preferredBitsPerPixel = 8;
483 Stream_Write_UINT16(s, preferredBitsPerPixel);
484 Stream_Write_UINT16(s, 1);
485 Stream_Write_UINT16(s, 1);
486 Stream_Write_UINT16(s, 1);
487 Stream_Write_UINT16(s, (UINT16)settings->DesktopWidth);
488 Stream_Write_UINT16(s, (UINT16)settings->DesktopHeight);
489 Stream_Write_UINT16(s, 0);
490 Stream_Write_UINT16(s, (UINT16)settings->DesktopResize);
491 Stream_Write_UINT16(s, 1);
492 Stream_Write_UINT8(s, 0);
493 Stream_Write_UINT8(s, drawingFlags);
494 Stream_Write_UINT16(s, 1);
495 Stream_Write_UINT16(s, 0);
496 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP);
499 #ifdef WITH_DEBUG_CAPABILITIES
500 static BOOL rdp_print_bitmap_capability_set(
wStream* s)
502 UINT16 preferredBitsPerPixel = 0;
503 UINT16 receive1BitPerPixel = 0;
504 UINT16 receive4BitsPerPixel = 0;
505 UINT16 receive8BitsPerPixel = 0;
506 UINT16 desktopWidth = 0;
507 UINT16 desktopHeight = 0;
508 UINT16 pad2Octets = 0;
509 UINT16 desktopResizeFlag = 0;
510 UINT16 bitmapCompressionFlag = 0;
511 BYTE highColorFlags = 0;
512 BYTE drawingFlags = 0;
513 UINT16 multipleRectangleSupport = 0;
514 UINT16 pad2OctetsB = 0;
515 WLog_VRB(TAG,
"BitmapCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
517 if (!Stream_CheckAndLogRequiredLength(TAG, s, 24))
520 Stream_Read_UINT16(s, preferredBitsPerPixel);
521 Stream_Read_UINT16(s, receive1BitPerPixel);
522 Stream_Read_UINT16(s, receive4BitsPerPixel);
523 Stream_Read_UINT16(s, receive8BitsPerPixel);
524 Stream_Read_UINT16(s, desktopWidth);
525 Stream_Read_UINT16(s, desktopHeight);
526 Stream_Read_UINT16(s, pad2Octets);
527 Stream_Read_UINT16(s, desktopResizeFlag);
528 Stream_Read_UINT16(s, bitmapCompressionFlag);
529 Stream_Read_UINT8(s, highColorFlags);
530 Stream_Read_UINT8(s, drawingFlags);
531 Stream_Read_UINT16(s, multipleRectangleSupport);
532 Stream_Read_UINT16(s, pad2OctetsB);
533 WLog_VRB(TAG,
"\tpreferredBitsPerPixel: 0x%04" PRIX16
"", preferredBitsPerPixel);
534 WLog_VRB(TAG,
"\treceive1BitPerPixel: 0x%04" PRIX16
"", receive1BitPerPixel);
535 WLog_VRB(TAG,
"\treceive4BitsPerPixel: 0x%04" PRIX16
"", receive4BitsPerPixel);
536 WLog_VRB(TAG,
"\treceive8BitsPerPixel: 0x%04" PRIX16
"", receive8BitsPerPixel);
537 WLog_VRB(TAG,
"\tdesktopWidth: 0x%04" PRIX16
"", desktopWidth);
538 WLog_VRB(TAG,
"\tdesktopHeight: 0x%04" PRIX16
"", desktopHeight);
539 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
540 WLog_VRB(TAG,
"\tdesktopResizeFlag: 0x%04" PRIX16
"", desktopResizeFlag);
541 WLog_VRB(TAG,
"\tbitmapCompressionFlag: 0x%04" PRIX16
"", bitmapCompressionFlag);
542 WLog_VRB(TAG,
"\thighColorFlags: 0x%02" PRIX8
"", highColorFlags);
543 WLog_VRB(TAG,
"\tdrawingFlags: 0x%02" PRIX8
"", drawingFlags);
544 WLog_VRB(TAG,
"\tmultipleRectangleSupport: 0x%04" PRIX16
"", multipleRectangleSupport);
545 WLog_VRB(TAG,
"\tpad2OctetsB: 0x%04" PRIX16
"", pad2OctetsB);
549 static BOOL rdp_apply_order_capability_set(rdpSettings* settings,
const rdpSettings* src)
551 WINPR_ASSERT(settings);
554 BOOL BitmapCacheV3Enabled = FALSE;
555 BOOL FrameMarkerCommandEnabled = FALSE;
557 for (
size_t i = 0; i < 32; i++)
559 if (!src->OrderSupport[i])
560 settings->OrderSupport[i] = FALSE;
563 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
565 if (src->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT)
566 BitmapCacheV3Enabled = TRUE;
568 if (src->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT)
569 FrameMarkerCommandEnabled = TRUE;
572 if (BitmapCacheV3Enabled)
574 settings->BitmapCacheV3Enabled = src->BitmapCacheV3Enabled;
575 settings->BitmapCacheVersion = src->BitmapCacheVersion;
578 settings->BitmapCacheV3Enabled = FALSE;
580 if (FrameMarkerCommandEnabled && !src->FrameMarkerCommandEnabled)
581 settings->FrameMarkerCommandEnabled = FALSE;
591 static BOOL rdp_read_order_capability_set(
wStream* s, rdpSettings* settings)
593 char terminalDescriptor[17] = { 0 };
594 BYTE orderSupport[32] = { 0 };
595 BOOL BitmapCacheV3Enabled = FALSE;
596 BOOL FrameMarkerCommandEnabled = FALSE;
598 WINPR_ASSERT(settings);
599 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
602 Stream_Read(s, terminalDescriptor, 16);
603 Stream_Seek_UINT32(s);
604 Stream_Seek_UINT16(s);
605 Stream_Seek_UINT16(s);
606 Stream_Seek_UINT16(s);
607 Stream_Seek_UINT16(s);
608 Stream_Seek_UINT16(s);
609 Stream_Read_UINT16(s, settings->OrderSupportFlags);
610 Stream_Read(s, orderSupport, 32);
611 Stream_Seek_UINT16(s);
612 Stream_Read_UINT16(s, settings->OrderSupportFlagsEx);
613 Stream_Seek_UINT32(s);
614 Stream_Seek_UINT32(s);
615 Stream_Seek_UINT16(s);
616 Stream_Seek_UINT16(s);
617 Stream_Read_UINT16(s, settings->TextANSICodePage);
618 Stream_Seek_UINT16(s);
623 for (
size_t i = 0; i < ARRAYSIZE(orderSupport); i++)
624 settings->OrderSupport[i] = orderSupport[i];
626 if (settings->OrderSupportFlags & ORDER_FLAGS_EXTRA_SUPPORT)
628 BitmapCacheV3Enabled =
629 (settings->OrderSupportFlagsEx & CACHE_BITMAP_V3_SUPPORT) ? TRUE : FALSE;
630 FrameMarkerCommandEnabled =
631 (settings->OrderSupportFlagsEx & ALTSEC_FRAME_MARKER_SUPPORT) ? TRUE : FALSE;
634 settings->BitmapCacheV3Enabled = BitmapCacheV3Enabled;
635 if (BitmapCacheV3Enabled)
636 settings->BitmapCacheVersion = 3;
638 settings->FrameMarkerCommandEnabled = FrameMarkerCommandEnabled;
648 static BOOL rdp_write_order_capability_set(
wStream* s,
const rdpSettings* settings)
650 char terminalDescriptor[16] = { 0 };
652 WINPR_ASSERT(settings);
653 if (!Stream_EnsureRemainingCapacity(s, 64))
656 const size_t header = rdp_capability_set_start(s);
658 UINT16 orderSupportExFlags = settings->OrderSupportFlagsEx;
659 UINT16 orderFlags = settings->OrderSupportFlags;
661 if (settings->BitmapCacheV3Enabled)
663 orderSupportExFlags |= CACHE_BITMAP_V3_SUPPORT;
664 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
667 if (settings->FrameMarkerCommandEnabled)
669 orderSupportExFlags |= ALTSEC_FRAME_MARKER_SUPPORT;
670 orderFlags |= ORDER_FLAGS_EXTRA_SUPPORT;
676 const size_t len = strnlen(dsc, ARRAYSIZE(terminalDescriptor));
677 strncpy(terminalDescriptor, dsc, len);
679 Stream_Write(s, terminalDescriptor,
680 sizeof(terminalDescriptor));
681 Stream_Write_UINT32(s, 0);
682 Stream_Write_UINT16(s, 1);
683 Stream_Write_UINT16(s, 20);
684 Stream_Write_UINT16(s, 0);
685 Stream_Write_UINT16(s, 1);
686 Stream_Write_UINT16(s, 0);
687 Stream_Write_UINT16(s, orderFlags);
688 Stream_Write(s, settings->OrderSupport, 32);
689 Stream_Write_UINT16(s, 0);
690 Stream_Write_UINT16(s, orderSupportExFlags);
691 Stream_Write_UINT32(s, 0);
692 Stream_Write_UINT32(s, 230400);
693 Stream_Write_UINT16(s, 0);
694 Stream_Write_UINT16(s, 0);
695 Stream_Write_UINT16(s, settings->TextANSICodePage);
696 Stream_Write_UINT16(s, 0);
697 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ORDER);
700 #ifdef WITH_DEBUG_CAPABILITIES
701 static BOOL rdp_print_order_capability_set(
wStream* s)
703 BYTE terminalDescriptor[16];
704 UINT32 pad4OctetsA = 0;
705 UINT16 desktopSaveXGranularity = 0;
706 UINT16 desktopSaveYGranularity = 0;
707 UINT16 pad2OctetsA = 0;
708 UINT16 maximumOrderLevel = 0;
709 UINT16 numberFonts = 0;
710 UINT16 orderFlags = 0;
711 BYTE orderSupport[32];
712 UINT16 textFlags = 0;
713 UINT16 orderSupportExFlags = 0;
714 UINT32 pad4OctetsB = 0;
715 UINT32 desktopSaveSize = 0;
716 UINT16 pad2OctetsC = 0;
717 UINT16 pad2OctetsD = 0;
718 UINT16 textANSICodePage = 0;
719 UINT16 pad2OctetsE = 0;
720 WLog_VRB(TAG,
"OrderCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
722 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
725 Stream_Read(s, terminalDescriptor, 16);
726 Stream_Read_UINT32(s, pad4OctetsA);
727 Stream_Read_UINT16(s, desktopSaveXGranularity);
728 Stream_Read_UINT16(s, desktopSaveYGranularity);
729 Stream_Read_UINT16(s, pad2OctetsA);
730 Stream_Read_UINT16(s, maximumOrderLevel);
731 Stream_Read_UINT16(s, numberFonts);
732 Stream_Read_UINT16(s, orderFlags);
733 Stream_Read(s, orderSupport, 32);
734 Stream_Read_UINT16(s, textFlags);
735 Stream_Read_UINT16(s, orderSupportExFlags);
736 Stream_Read_UINT32(s, pad4OctetsB);
737 Stream_Read_UINT32(s, desktopSaveSize);
738 Stream_Read_UINT16(s, pad2OctetsC);
739 Stream_Read_UINT16(s, pad2OctetsD);
740 Stream_Read_UINT16(s, textANSICodePage);
741 Stream_Read_UINT16(s, pad2OctetsE);
742 WLog_VRB(TAG,
"\tpad4OctetsA: 0x%08" PRIX32
"", pad4OctetsA);
743 WLog_VRB(TAG,
"\tdesktopSaveXGranularity: 0x%04" PRIX16
"", desktopSaveXGranularity);
744 WLog_VRB(TAG,
"\tdesktopSaveYGranularity: 0x%04" PRIX16
"", desktopSaveYGranularity);
745 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
746 WLog_VRB(TAG,
"\tmaximumOrderLevel: 0x%04" PRIX16
"", maximumOrderLevel);
747 WLog_VRB(TAG,
"\tnumberFonts: 0x%04" PRIX16
"", numberFonts);
748 WLog_VRB(TAG,
"\torderFlags: 0x%04" PRIX16
"", orderFlags);
749 WLog_VRB(TAG,
"\torderSupport:");
750 WLog_VRB(TAG,
"\t\tDSTBLT: %" PRIu8
"", orderSupport[NEG_DSTBLT_INDEX]);
751 WLog_VRB(TAG,
"\t\tPATBLT: %" PRIu8
"", orderSupport[NEG_PATBLT_INDEX]);
752 WLog_VRB(TAG,
"\t\tSCRBLT: %" PRIu8
"", orderSupport[NEG_SCRBLT_INDEX]);
753 WLog_VRB(TAG,
"\t\tMEMBLT: %" PRIu8
"", orderSupport[NEG_MEMBLT_INDEX]);
754 WLog_VRB(TAG,
"\t\tMEM3BLT: %" PRIu8
"", orderSupport[NEG_MEM3BLT_INDEX]);
755 WLog_VRB(TAG,
"\t\tATEXTOUT: %" PRIu8
"", orderSupport[NEG_ATEXTOUT_INDEX]);
756 WLog_VRB(TAG,
"\t\tAEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_AEXTTEXTOUT_INDEX]);
757 WLog_VRB(TAG,
"\t\tDRAWNINEGRID: %" PRIu8
"", orderSupport[NEG_DRAWNINEGRID_INDEX]);
758 WLog_VRB(TAG,
"\t\tLINETO: %" PRIu8
"", orderSupport[NEG_LINETO_INDEX]);
759 WLog_VRB(TAG,
"\t\tMULTI_DRAWNINEGRID: %" PRIu8
"", orderSupport[NEG_MULTI_DRAWNINEGRID_INDEX]);
760 WLog_VRB(TAG,
"\t\tOPAQUE_RECT: %" PRIu8
"", orderSupport[NEG_OPAQUE_RECT_INDEX]);
761 WLog_VRB(TAG,
"\t\tSAVEBITMAP: %" PRIu8
"", orderSupport[NEG_SAVEBITMAP_INDEX]);
762 WLog_VRB(TAG,
"\t\tWTEXTOUT: %" PRIu8
"", orderSupport[NEG_WTEXTOUT_INDEX]);
763 WLog_VRB(TAG,
"\t\tMEMBLT_V2: %" PRIu8
"", orderSupport[NEG_MEMBLT_V2_INDEX]);
764 WLog_VRB(TAG,
"\t\tMEM3BLT_V2: %" PRIu8
"", orderSupport[NEG_MEM3BLT_V2_INDEX]);
765 WLog_VRB(TAG,
"\t\tMULTIDSTBLT: %" PRIu8
"", orderSupport[NEG_MULTIDSTBLT_INDEX]);
766 WLog_VRB(TAG,
"\t\tMULTIPATBLT: %" PRIu8
"", orderSupport[NEG_MULTIPATBLT_INDEX]);
767 WLog_VRB(TAG,
"\t\tMULTISCRBLT: %" PRIu8
"", orderSupport[NEG_MULTISCRBLT_INDEX]);
768 WLog_VRB(TAG,
"\t\tMULTIOPAQUERECT: %" PRIu8
"", orderSupport[NEG_MULTIOPAQUERECT_INDEX]);
769 WLog_VRB(TAG,
"\t\tFAST_INDEX: %" PRIu8
"", orderSupport[NEG_FAST_INDEX_INDEX]);
770 WLog_VRB(TAG,
"\t\tPOLYGON_SC: %" PRIu8
"", orderSupport[NEG_POLYGON_SC_INDEX]);
771 WLog_VRB(TAG,
"\t\tPOLYGON_CB: %" PRIu8
"", orderSupport[NEG_POLYGON_CB_INDEX]);
772 WLog_VRB(TAG,
"\t\tPOLYLINE: %" PRIu8
"", orderSupport[NEG_POLYLINE_INDEX]);
773 WLog_VRB(TAG,
"\t\tUNUSED23: %" PRIu8
"", orderSupport[NEG_UNUSED23_INDEX]);
774 WLog_VRB(TAG,
"\t\tFAST_GLYPH: %" PRIu8
"", orderSupport[NEG_FAST_GLYPH_INDEX]);
775 WLog_VRB(TAG,
"\t\tELLIPSE_SC: %" PRIu8
"", orderSupport[NEG_ELLIPSE_SC_INDEX]);
776 WLog_VRB(TAG,
"\t\tELLIPSE_CB: %" PRIu8
"", orderSupport[NEG_ELLIPSE_CB_INDEX]);
777 WLog_VRB(TAG,
"\t\tGLYPH_INDEX: %" PRIu8
"", orderSupport[NEG_GLYPH_INDEX_INDEX]);
778 WLog_VRB(TAG,
"\t\tGLYPH_WEXTTEXTOUT: %" PRIu8
"", orderSupport[NEG_GLYPH_WEXTTEXTOUT_INDEX]);
779 WLog_VRB(TAG,
"\t\tGLYPH_WLONGTEXTOUT: %" PRIu8
"", orderSupport[NEG_GLYPH_WLONGTEXTOUT_INDEX]);
780 WLog_VRB(TAG,
"\t\tGLYPH_WLONGEXTTEXTOUT: %" PRIu8
"",
781 orderSupport[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX]);
782 WLog_VRB(TAG,
"\t\tUNUSED31: %" PRIu8
"", orderSupport[NEG_UNUSED31_INDEX]);
783 WLog_VRB(TAG,
"\ttextFlags: 0x%04" PRIX16
"", textFlags);
784 WLog_VRB(TAG,
"\torderSupportExFlags: 0x%04" PRIX16
"", orderSupportExFlags);
785 WLog_VRB(TAG,
"\tpad4OctetsB: 0x%08" PRIX32
"", pad4OctetsB);
786 WLog_VRB(TAG,
"\tdesktopSaveSize: 0x%08" PRIX32
"", desktopSaveSize);
787 WLog_VRB(TAG,
"\tpad2OctetsC: 0x%04" PRIX16
"", pad2OctetsC);
788 WLog_VRB(TAG,
"\tpad2OctetsD: 0x%04" PRIX16
"", pad2OctetsD);
789 WLog_VRB(TAG,
"\ttextANSICodePage: 0x%04" PRIX16
"", textANSICodePage);
790 WLog_VRB(TAG,
"\tpad2OctetsE: 0x%04" PRIX16
"", pad2OctetsE);
795 static BOOL rdp_apply_bitmap_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
797 WINPR_ASSERT(settings);
807 static BOOL rdp_read_bitmap_cache_capability_set(
wStream* s, rdpSettings* settings)
809 WINPR_UNUSED(settings);
810 WINPR_ASSERT(settings);
812 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
815 Stream_Seek_UINT32(s);
816 Stream_Seek_UINT32(s);
817 Stream_Seek_UINT32(s);
818 Stream_Seek_UINT32(s);
819 Stream_Seek_UINT32(s);
820 Stream_Seek_UINT32(s);
821 Stream_Seek_UINT16(s);
822 Stream_Seek_UINT16(s);
823 Stream_Seek_UINT16(s);
824 Stream_Seek_UINT16(s);
825 Stream_Seek_UINT16(s);
826 Stream_Seek_UINT16(s);
835 static BOOL rdp_write_bitmap_cache_capability_set(
wStream* s,
const rdpSettings* settings)
837 if (!Stream_EnsureRemainingCapacity(s, 64))
840 const size_t header = rdp_capability_set_start(s);
842 if (bpp > UINT16_MAX)
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 Stream_Write_UINT32(s, 0);
849 Stream_Write_UINT32(s, 0);
850 UINT32 size = bpp * 256;
851 if (size > UINT16_MAX)
853 Stream_Write_UINT16(s, 200);
854 Stream_Write_UINT16(s, (UINT16)size);
856 if (size > UINT16_MAX)
858 Stream_Write_UINT16(s, 600);
859 Stream_Write_UINT16(s, (UINT16)size);
861 if (size > UINT16_MAX)
863 Stream_Write_UINT16(s, 1000);
864 Stream_Write_UINT16(s, (UINT16)size);
865 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE);
868 #ifdef WITH_DEBUG_CAPABILITIES
869 static BOOL rdp_print_bitmap_cache_capability_set(
wStream* s)
877 UINT16 Cache0Entries = 0;
878 UINT16 Cache0MaximumCellSize = 0;
879 UINT16 Cache1Entries = 0;
880 UINT16 Cache1MaximumCellSize = 0;
881 UINT16 Cache2Entries = 0;
882 UINT16 Cache2MaximumCellSize = 0;
883 WLog_VRB(TAG,
"BitmapCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
885 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
888 Stream_Read_UINT32(s, pad1);
889 Stream_Read_UINT32(s, pad2);
890 Stream_Read_UINT32(s, pad3);
891 Stream_Read_UINT32(s, pad4);
892 Stream_Read_UINT32(s, pad5);
893 Stream_Read_UINT32(s, pad6);
894 Stream_Read_UINT16(s, Cache0Entries);
895 Stream_Read_UINT16(s, Cache0MaximumCellSize);
896 Stream_Read_UINT16(s, Cache1Entries);
897 Stream_Read_UINT16(s, Cache1MaximumCellSize);
898 Stream_Read_UINT16(s, Cache2Entries);
899 Stream_Read_UINT16(s, Cache2MaximumCellSize);
900 WLog_VRB(TAG,
"\tpad1: 0x%08" PRIX32
"", pad1);
901 WLog_VRB(TAG,
"\tpad2: 0x%08" PRIX32
"", pad2);
902 WLog_VRB(TAG,
"\tpad3: 0x%08" PRIX32
"", pad3);
903 WLog_VRB(TAG,
"\tpad4: 0x%08" PRIX32
"", pad4);
904 WLog_VRB(TAG,
"\tpad5: 0x%08" PRIX32
"", pad5);
905 WLog_VRB(TAG,
"\tpad6: 0x%08" PRIX32
"", pad6);
906 WLog_VRB(TAG,
"\tCache0Entries: 0x%04" PRIX16
"", Cache0Entries);
907 WLog_VRB(TAG,
"\tCache0MaximumCellSize: 0x%04" PRIX16
"", Cache0MaximumCellSize);
908 WLog_VRB(TAG,
"\tCache1Entries: 0x%04" PRIX16
"", Cache1Entries);
909 WLog_VRB(TAG,
"\tCache1MaximumCellSize: 0x%04" PRIX16
"", Cache1MaximumCellSize);
910 WLog_VRB(TAG,
"\tCache2Entries: 0x%04" PRIX16
"", Cache2Entries);
911 WLog_VRB(TAG,
"\tCache2MaximumCellSize: 0x%04" PRIX16
"", Cache2MaximumCellSize);
916 static BOOL rdp_apply_control_capability_set(rdpSettings* settings,
const rdpSettings* src)
918 WINPR_ASSERT(settings);
929 static BOOL rdp_read_control_capability_set(
wStream* s, rdpSettings* settings)
931 WINPR_UNUSED(settings);
932 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
935 Stream_Seek_UINT16(s);
936 Stream_Seek_UINT16(s);
937 Stream_Seek_UINT16(s);
938 Stream_Seek_UINT16(s);
947 static BOOL rdp_write_control_capability_set(
wStream* s,
const rdpSettings* settings)
949 WINPR_UNUSED(settings);
950 if (!Stream_EnsureRemainingCapacity(s, 32))
953 const size_t header = rdp_capability_set_start(s);
954 Stream_Write_UINT16(s, 0);
955 Stream_Write_UINT16(s, 0);
956 Stream_Write_UINT16(s, 2);
957 Stream_Write_UINT16(s, 2);
958 return rdp_capability_set_finish(s, header, CAPSET_TYPE_CONTROL);
961 #ifdef WITH_DEBUG_CAPABILITIES
962 static BOOL rdp_print_control_capability_set(
wStream* s)
964 UINT16 controlFlags = 0;
965 UINT16 remoteDetachFlag = 0;
966 UINT16 controlInterest = 0;
967 UINT16 detachInterest = 0;
968 WLog_VRB(TAG,
"ControlCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
970 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
973 Stream_Read_UINT16(s, controlFlags);
974 Stream_Read_UINT16(s, remoteDetachFlag);
975 Stream_Read_UINT16(s, controlInterest);
976 Stream_Read_UINT16(s, detachInterest);
977 WLog_VRB(TAG,
"\tcontrolFlags: 0x%04" PRIX16
"", controlFlags);
978 WLog_VRB(TAG,
"\tremoteDetachFlag: 0x%04" PRIX16
"", remoteDetachFlag);
979 WLog_VRB(TAG,
"\tcontrolInterest: 0x%04" PRIX16
"", controlInterest);
980 WLog_VRB(TAG,
"\tdetachInterest: 0x%04" PRIX16
"", detachInterest);
985 static BOOL rdp_apply_window_activation_capability_set(rdpSettings* settings,
986 const rdpSettings* src)
988 WINPR_ASSERT(settings);
999 static BOOL rdp_read_window_activation_capability_set(
wStream* s, rdpSettings* settings)
1001 WINPR_UNUSED(settings);
1002 WINPR_ASSERT(settings);
1003 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1006 Stream_Seek_UINT16(s);
1007 Stream_Seek_UINT16(s);
1008 Stream_Seek_UINT16(s);
1009 Stream_Seek_UINT16(s);
1018 static BOOL rdp_write_window_activation_capability_set(
wStream* s,
const rdpSettings* settings)
1020 WINPR_UNUSED(settings);
1021 WINPR_ASSERT(settings);
1022 if (!Stream_EnsureRemainingCapacity(s, 32))
1025 const size_t header = rdp_capability_set_start(s);
1026 Stream_Write_UINT16(s, 0);
1027 Stream_Write_UINT16(s, 0);
1028 Stream_Write_UINT16(s, 0);
1029 Stream_Write_UINT16(s, 0);
1030 return rdp_capability_set_finish(s, header, CAPSET_TYPE_ACTIVATION);
1033 #ifdef WITH_DEBUG_CAPABILITIES
1034 static BOOL rdp_print_window_activation_capability_set(
wStream* s)
1036 UINT16 helpKeyFlag = 0;
1037 UINT16 helpKeyIndexFlag = 0;
1038 UINT16 helpExtendedKeyFlag = 0;
1039 UINT16 windowManagerKeyFlag = 0;
1041 "WindowActivationCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1043 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1046 Stream_Read_UINT16(s, helpKeyFlag);
1047 Stream_Read_UINT16(s, helpKeyIndexFlag);
1048 Stream_Read_UINT16(s, helpExtendedKeyFlag);
1049 Stream_Read_UINT16(s, windowManagerKeyFlag);
1050 WLog_VRB(TAG,
"\thelpKeyFlag: 0x%04" PRIX16
"", helpKeyFlag);
1051 WLog_VRB(TAG,
"\thelpKeyIndexFlag: 0x%04" PRIX16
"", helpKeyIndexFlag);
1052 WLog_VRB(TAG,
"\thelpExtendedKeyFlag: 0x%04" PRIX16
"", helpExtendedKeyFlag);
1053 WLog_VRB(TAG,
"\twindowManagerKeyFlag: 0x%04" PRIX16
"", windowManagerKeyFlag);
1058 static BOOL rdp_apply_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
1060 WINPR_ASSERT(settings);
1064 const UINT32 colorPointerCacheSize =
1066 const UINT32 dstPointerCacheSize =
1068 const UINT32 dstColorPointerCacheSize =
1072 const UINT32 actualPointerCacheSize = MIN(pointerCacheSize, dstPointerCacheSize);
1073 const UINT32 actualColorPointerCacheSize = MIN(colorPointerCacheSize, dstColorPointerCacheSize);
1077 actualColorPointerCacheSize))
1088 static BOOL rdp_read_pointer_capability_set(
wStream* s, rdpSettings* settings)
1090 UINT16 colorPointerFlag = 0;
1091 UINT16 colorPointerCacheSize = 0;
1092 UINT16 pointerCacheSize = 0;
1094 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1097 Stream_Read_UINT16(s, colorPointerFlag);
1098 Stream_Read_UINT16(s, colorPointerCacheSize);
1100 if (colorPointerFlag == 0)
1102 WLog_WARN(TAG,
"[MS-RDPBCGR] 2.2.7.1.5 Pointer Capability Set "
1103 "(TS_POINTER_CAPABILITYSET)::colorPointerFlag received is %" PRIu16
1104 ". Value is ignored and always assumed to be TRUE");
1108 if (Stream_GetRemainingLength(s) >= 2)
1109 Stream_Read_UINT16(s, pointerCacheSize);
1111 WINPR_ASSERT(settings);
1112 settings->PointerCacheSize = pointerCacheSize;
1113 settings->ColorPointerCacheSize = colorPointerCacheSize;
1123 static BOOL rdp_write_pointer_capability_set(
wStream* s,
const rdpSettings* settings)
1125 if (!Stream_EnsureRemainingCapacity(s, 32))
1128 const size_t header = rdp_capability_set_start(s);
1129 if (settings->PointerCacheSize > UINT16_MAX)
1131 if (settings->ColorPointerCacheSize > UINT16_MAX)
1134 WINPR_ASSERT(settings);
1135 const UINT32 colorPointerFlag =
1138 Stream_Write_UINT16(s, colorPointerFlag);
1139 Stream_Write_UINT16(
1140 s, (UINT16)settings->ColorPointerCacheSize);
1141 Stream_Write_UINT16(s, (UINT16)settings->PointerCacheSize);
1143 return rdp_capability_set_finish(s, header, CAPSET_TYPE_POINTER);
1146 #ifdef WITH_DEBUG_CAPABILITIES
1147 static BOOL rdp_print_pointer_capability_set(
wStream* s)
1149 UINT16 colorPointerFlag = 0;
1150 UINT16 colorPointerCacheSize = 0;
1151 UINT16 pointerCacheSize = 0;
1153 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1156 WLog_VRB(TAG,
"PointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1157 Stream_Read_UINT16(s, colorPointerFlag);
1158 Stream_Read_UINT16(s, colorPointerCacheSize);
1159 Stream_Read_UINT16(s, pointerCacheSize);
1160 WLog_VRB(TAG,
"\tcolorPointerFlag: 0x%04" PRIX16
"", colorPointerFlag);
1161 WLog_VRB(TAG,
"\tcolorPointerCacheSize: 0x%04" PRIX16
"", colorPointerCacheSize);
1162 WLog_VRB(TAG,
"\tpointerCacheSize: 0x%04" PRIX16
"", pointerCacheSize);
1167 static BOOL rdp_apply_share_capability_set(rdpSettings* settings,
const rdpSettings* src)
1169 WINPR_ASSERT(settings);
1180 static BOOL rdp_read_share_capability_set(
wStream* s, rdpSettings* settings)
1182 WINPR_UNUSED(settings);
1183 WINPR_ASSERT(settings);
1185 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1188 Stream_Seek_UINT16(s);
1189 Stream_Seek_UINT16(s);
1198 static BOOL rdp_write_share_capability_set(
wStream* s,
const rdpSettings* settings)
1200 if (!Stream_EnsureRemainingCapacity(s, 32))
1203 const size_t header = rdp_capability_set_start(s);
1205 WINPR_ASSERT(settings);
1206 const UINT16 nodeId = (settings->ServerMode) ? 0x03EA : 0;
1207 Stream_Write_UINT16(s, nodeId);
1208 Stream_Write_UINT16(s, 0);
1209 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SHARE);
1212 #ifdef WITH_DEBUG_CAPABILITIES
1213 static BOOL rdp_print_share_capability_set(
wStream* s)
1216 UINT16 pad2Octets = 0;
1217 WLog_VRB(TAG,
"ShareCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1219 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1222 Stream_Read_UINT16(s, nodeId);
1223 Stream_Read_UINT16(s, pad2Octets);
1224 WLog_VRB(TAG,
"\tnodeId: 0x%04" PRIX16
"", nodeId);
1225 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1230 static BOOL rdp_apply_color_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1232 WINPR_ASSERT(settings);
1242 static BOOL rdp_read_color_cache_capability_set(
wStream* s, rdpSettings* settings)
1244 WINPR_UNUSED(settings);
1245 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1248 Stream_Seek_UINT16(s);
1249 Stream_Seek_UINT16(s);
1258 static BOOL rdp_write_color_cache_capability_set(
wStream* s,
const rdpSettings* settings)
1260 WINPR_UNUSED(settings);
1261 if (!Stream_EnsureRemainingCapacity(s, 32))
1264 const size_t header = rdp_capability_set_start(s);
1265 Stream_Write_UINT16(s, 6);
1266 Stream_Write_UINT16(s, 0);
1267 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COLOR_CACHE);
1270 #ifdef WITH_DEBUG_CAPABILITIES
1271 static BOOL rdp_print_color_cache_capability_set(
wStream* s)
1273 UINT16 colorTableCacheSize = 0;
1274 UINT16 pad2Octets = 0;
1275 WLog_VRB(TAG,
"ColorCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1277 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1280 Stream_Read_UINT16(s, colorTableCacheSize);
1281 Stream_Read_UINT16(s, pad2Octets);
1282 WLog_VRB(TAG,
"\tcolorTableCacheSize: 0x%04" PRIX16
"", colorTableCacheSize);
1283 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1288 static BOOL rdp_apply_sound_capability_set(rdpSettings* settings,
const rdpSettings* src)
1290 WINPR_ASSERT(settings);
1293 settings->SoundBeepsEnabled = src->SoundBeepsEnabled;
1303 static BOOL rdp_read_sound_capability_set(
wStream* s, rdpSettings* settings)
1305 UINT16 soundFlags = 0;
1307 WINPR_ASSERT(settings);
1308 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1311 Stream_Read_UINT16(s, soundFlags);
1312 Stream_Seek_UINT16(s);
1313 settings->SoundBeepsEnabled = (soundFlags & SOUND_BEEPS_FLAG) ? TRUE : FALSE;
1322 static BOOL rdp_write_sound_capability_set(
wStream* s,
const rdpSettings* settings)
1324 WINPR_ASSERT(settings);
1325 if (!Stream_EnsureRemainingCapacity(s, 32))
1328 const size_t header = rdp_capability_set_start(s);
1329 const UINT16 soundFlags = (settings->SoundBeepsEnabled) ? SOUND_BEEPS_FLAG : 0;
1330 Stream_Write_UINT16(s, soundFlags);
1331 Stream_Write_UINT16(s, 0);
1332 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SOUND);
1335 #ifdef WITH_DEBUG_CAPABILITIES
1336 static BOOL rdp_print_sound_capability_set(
wStream* s)
1338 UINT16 soundFlags = 0;
1339 UINT16 pad2OctetsA = 0;
1340 WLog_VRB(TAG,
"SoundCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1342 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1345 Stream_Read_UINT16(s, soundFlags);
1346 Stream_Read_UINT16(s, pad2OctetsA);
1347 WLog_VRB(TAG,
"\tsoundFlags: 0x%04" PRIX16
"", soundFlags);
1348 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1353 static BOOL rdp_apply_input_capability_set(rdpSettings* settings,
const rdpSettings* src)
1355 WINPR_ASSERT(settings);
1358 if (settings->ServerMode)
1360 settings->KeyboardLayout = src->KeyboardLayout;
1361 settings->KeyboardType = src->KeyboardType;
1362 settings->KeyboardSubType = src->KeyboardSubType;
1363 settings->KeyboardFunctionKey = src->KeyboardFunctionKey;
1369 if (!settings->ServerMode)
1371 settings->FastPathInput = src->FastPathInput;
1377 if (settings->HasHorizontalWheel)
1378 settings->HasHorizontalWheel = src->HasHorizontalWheel;
1386 if (settings->HasExtendedMouseEvent)
1387 settings->HasExtendedMouseEvent = src->HasExtendedMouseEvent;
1388 if (settings->HasRelativeMouseEvent)
1389 settings->HasRelativeMouseEvent = src->HasRelativeMouseEvent;
1401 static BOOL rdp_read_input_capability_set(
wStream* s, rdpSettings* settings)
1403 UINT16 inputFlags = 0;
1405 WINPR_ASSERT(settings);
1406 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
1409 Stream_Read_UINT16(s, inputFlags);
1410 Stream_Seek_UINT16(s);
1412 Stream_Read_UINT32(s, settings->KeyboardLayout);
1413 Stream_Read_UINT32(s, settings->KeyboardType);
1414 Stream_Read_UINT32(s, settings->KeyboardSubType);
1415 Stream_Read_UINT32(s, settings->KeyboardFunctionKey);
1418 WCHAR wstr[32] = { 0 };
1419 char str[65] = { 0 };
1425 if (!Stream_Read_UTF16_String(s, wstr, ARRAYSIZE(wstr)))
1428 if (ConvertWCharNToUtf8(wstr, ARRAYSIZE(wstr), str, ARRAYSIZE(str)) < 0)
1429 memset(str, 0,
sizeof(str));
1437 (INPUT_FLAG_FASTPATH_INPUT | INPUT_FLAG_FASTPATH_INPUT2)))
1440 (inputFlags & TS_INPUT_FLAG_MOUSE_HWHEEL) ? TRUE : FALSE))
1443 (inputFlags & INPUT_FLAG_UNICODE) ? TRUE : FALSE))
1446 (inputFlags & INPUT_FLAG_MOUSE_RELATIVE) ? TRUE : FALSE))
1449 (inputFlags & INPUT_FLAG_MOUSEX) ? TRUE : FALSE))
1452 (inputFlags & TS_INPUT_FLAG_QOE_TIMESTAMPS) ? TRUE : FALSE))
1463 static BOOL rdp_write_input_capability_set(
wStream* s,
const rdpSettings* settings)
1465 WINPR_ASSERT(settings);
1466 if (!Stream_EnsureRemainingCapacity(s, 128))
1469 const size_t header = rdp_capability_set_start(s);
1470 UINT16 inputFlags = INPUT_FLAG_SCANCODES;
1472 if (settings->FastPathInput)
1474 inputFlags |= INPUT_FLAG_FASTPATH_INPUT;
1475 inputFlags |= INPUT_FLAG_FASTPATH_INPUT2;
1479 inputFlags |= INPUT_FLAG_MOUSE_RELATIVE;
1482 inputFlags |= TS_INPUT_FLAG_MOUSE_HWHEEL;
1485 inputFlags |= INPUT_FLAG_UNICODE;
1488 inputFlags |= TS_INPUT_FLAG_QOE_TIMESTAMPS;
1490 if (settings->HasExtendedMouseEvent)
1491 inputFlags |= INPUT_FLAG_MOUSEX;
1493 Stream_Write_UINT16(s, inputFlags);
1494 Stream_Write_UINT16(s, 0);
1495 Stream_Write_UINT32(s, settings->KeyboardLayout);
1496 Stream_Write_UINT32(s, settings->KeyboardType);
1497 Stream_Write_UINT32(s, settings->KeyboardSubType);
1498 Stream_Write_UINT32(s, settings->KeyboardFunctionKey);
1500 return rdp_capability_set_finish(s, header, CAPSET_TYPE_INPUT);
1503 #ifdef WITH_DEBUG_CAPABILITIES
1504 static BOOL rdp_print_input_capability_set(
wStream* s)
1506 UINT16 inputFlags = 0;
1507 UINT16 pad2OctetsA = 0;
1508 UINT32 keyboardLayout = 0;
1509 UINT32 keyboardType = 0;
1510 UINT32 keyboardSubType = 0;
1511 UINT32 keyboardFunctionKey = 0;
1512 WLog_VRB(TAG,
"InputCapabilitySet (length %" PRIuz
")", Stream_GetRemainingLength(s));
1514 if (!Stream_CheckAndLogRequiredLength(TAG, s, 84))
1517 Stream_Read_UINT16(s, inputFlags);
1518 Stream_Read_UINT16(s, pad2OctetsA);
1519 Stream_Read_UINT32(s, keyboardLayout);
1520 Stream_Read_UINT32(s, keyboardType);
1521 Stream_Read_UINT32(s, keyboardSubType);
1522 Stream_Read_UINT32(s, keyboardFunctionKey);
1524 WLog_VRB(TAG,
"\tinputFlags: 0x%04" PRIX16
"", inputFlags);
1525 WLog_VRB(TAG,
"\tpad2OctetsA: 0x%04" PRIX16
"", pad2OctetsA);
1526 WLog_VRB(TAG,
"\tkeyboardLayout: 0x%08" PRIX32
"", keyboardLayout);
1527 WLog_VRB(TAG,
"\tkeyboardType: 0x%08" PRIX32
"", keyboardType);
1528 WLog_VRB(TAG,
"\tkeyboardSubType: 0x%08" PRIX32
"", keyboardSubType);
1529 WLog_VRB(TAG,
"\tkeyboardFunctionKey: 0x%08" PRIX32
"", keyboardFunctionKey);
1534 static BOOL rdp_apply_font_capability_set(rdpSettings* settings,
const rdpSettings* src)
1536 WINPR_ASSERT(settings);
1546 static BOOL rdp_read_font_capability_set(
wStream* s, rdpSettings* settings)
1548 WINPR_UNUSED(settings);
1549 if (Stream_GetRemainingLength(s) >= 2)
1550 Stream_Seek_UINT16(s);
1552 if (Stream_GetRemainingLength(s) >= 2)
1553 Stream_Seek_UINT16(s);
1563 static BOOL rdp_write_font_capability_set(
wStream* s,
const rdpSettings* settings)
1565 WINPR_UNUSED(settings);
1566 if (!Stream_EnsureRemainingCapacity(s, 32))
1569 const size_t header = rdp_capability_set_start(s);
1570 Stream_Write_UINT16(s, FONTSUPPORT_FONTLIST);
1571 Stream_Write_UINT16(s, 0);
1572 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FONT);
1575 #ifdef WITH_DEBUG_CAPABILITIES
1576 static BOOL rdp_print_font_capability_set(
wStream* s)
1578 UINT16 fontSupportFlags = 0;
1579 UINT16 pad2Octets = 0;
1580 WLog_VRB(TAG,
"FontCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1582 if (Stream_GetRemainingLength(s) >= 2)
1583 Stream_Read_UINT16(s, fontSupportFlags);
1585 if (Stream_GetRemainingLength(s) >= 2)
1586 Stream_Read_UINT16(s, pad2Octets);
1588 WLog_VRB(TAG,
"\tfontSupportFlags: 0x%04" PRIX16
"", fontSupportFlags);
1589 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1594 static BOOL rdp_apply_brush_capability_set(rdpSettings* settings,
const rdpSettings* src)
1596 WINPR_ASSERT(settings);
1600 settings->BrushSupportLevel = src->BrushSupportLevel;
1609 static BOOL rdp_read_brush_capability_set(
wStream* s, rdpSettings* settings)
1611 WINPR_UNUSED(settings);
1612 WINPR_ASSERT(settings);
1614 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1616 Stream_Read_UINT32(s, settings->BrushSupportLevel);
1625 static BOOL rdp_write_brush_capability_set(
wStream* s,
const rdpSettings* settings)
1627 WINPR_ASSERT(settings);
1628 if (!Stream_EnsureRemainingCapacity(s, 32))
1631 const size_t header = rdp_capability_set_start(s);
1632 Stream_Write_UINT32(s, settings->BrushSupportLevel);
1633 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BRUSH);
1636 #ifdef WITH_DEBUG_CAPABILITIES
1637 static BOOL rdp_print_brush_capability_set(
wStream* s)
1639 UINT32 brushSupportLevel = 0;
1640 WLog_VRB(TAG,
"BrushCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1642 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1645 Stream_Read_UINT32(s, brushSupportLevel);
1646 WLog_VRB(TAG,
"\tbrushSupportLevel: 0x%08" PRIX32
"", brushSupportLevel);
1657 WINPR_ASSERT(cache_definition);
1658 Stream_Read_UINT16(s, cache_definition->cacheEntries);
1659 Stream_Read_UINT16(s,
1660 cache_definition->cacheMaximumCellSize);
1669 WINPR_ASSERT(cache_definition);
1670 Stream_Write_UINT16(s, cache_definition->cacheEntries);
1671 Stream_Write_UINT16(
1672 s, cache_definition->cacheMaximumCellSize);
1675 static BOOL rdp_apply_glyph_cache_capability_set(rdpSettings* settings,
const rdpSettings* src)
1677 WINPR_ASSERT(settings);
1680 WINPR_ASSERT(src->GlyphCache);
1681 WINPR_ASSERT(settings->GlyphCache);
1682 for (
size_t x = 0; x < 10; x++)
1683 settings->GlyphCache[x] = src->GlyphCache[x];
1685 WINPR_ASSERT(src->FragCache);
1686 WINPR_ASSERT(settings->FragCache);
1687 settings->FragCache[0] = src->FragCache[0];
1688 settings->GlyphSupportLevel = src->GlyphSupportLevel;
1698 static BOOL rdp_read_glyph_cache_capability_set(
wStream* s, rdpSettings* settings)
1700 WINPR_ASSERT(settings);
1701 if (!Stream_CheckAndLogRequiredLength(TAG, s, 48))
1705 for (
size_t x = 0; x < 10; x++)
1706 rdp_read_cache_definition(s, &(settings->GlyphCache[x]));
1707 rdp_read_cache_definition(s, settings->FragCache);
1708 Stream_Read_UINT16(s, settings->GlyphSupportLevel);
1709 Stream_Seek_UINT16(s);
1718 static BOOL rdp_write_glyph_cache_capability_set(
wStream* s,
const rdpSettings* settings)
1720 WINPR_ASSERT(settings);
1721 if (!Stream_EnsureRemainingCapacity(s, 64))
1724 const size_t header = rdp_capability_set_start(s);
1725 if (settings->GlyphSupportLevel > UINT16_MAX)
1728 for (
size_t x = 0; x < 10; x++)
1729 rdp_write_cache_definition(s, &(settings->GlyphCache[x]));
1730 rdp_write_cache_definition(s, settings->FragCache);
1731 Stream_Write_UINT16(s, (UINT16)settings->GlyphSupportLevel);
1732 Stream_Write_UINT16(s, 0);
1733 return rdp_capability_set_finish(s, header, CAPSET_TYPE_GLYPH_CACHE);
1736 #ifdef WITH_DEBUG_CAPABILITIES
1737 static BOOL rdp_print_glyph_cache_capability_set(
wStream* s)
1741 UINT16 glyphSupportLevel = 0;
1742 UINT16 pad2Octets = 0;
1743 WLog_VRB(TAG,
"GlyphCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
1745 if (!Stream_CheckAndLogRequiredLength(TAG, s, 48))
1749 rdp_read_cache_definition(s, &glyphCache[0]);
1750 rdp_read_cache_definition(s, &glyphCache[1]);
1751 rdp_read_cache_definition(s, &glyphCache[2]);
1752 rdp_read_cache_definition(s, &glyphCache[3]);
1753 rdp_read_cache_definition(s, &glyphCache[4]);
1754 rdp_read_cache_definition(s, &glyphCache[5]);
1755 rdp_read_cache_definition(s, &glyphCache[6]);
1756 rdp_read_cache_definition(s, &glyphCache[7]);
1757 rdp_read_cache_definition(s, &glyphCache[8]);
1758 rdp_read_cache_definition(s, &glyphCache[9]);
1759 rdp_read_cache_definition(s, &fragCache);
1760 Stream_Read_UINT16(s, glyphSupportLevel);
1761 Stream_Read_UINT16(s, pad2Octets);
1762 WLog_VRB(TAG,
"\tglyphCache0: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1763 glyphCache[0].cacheEntries, glyphCache[0].cacheMaximumCellSize);
1764 WLog_VRB(TAG,
"\tglyphCache1: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1765 glyphCache[1].cacheEntries, glyphCache[1].cacheMaximumCellSize);
1766 WLog_VRB(TAG,
"\tglyphCache2: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1767 glyphCache[2].cacheEntries, glyphCache[2].cacheMaximumCellSize);
1768 WLog_VRB(TAG,
"\tglyphCache3: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1769 glyphCache[3].cacheEntries, glyphCache[3].cacheMaximumCellSize);
1770 WLog_VRB(TAG,
"\tglyphCache4: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1771 glyphCache[4].cacheEntries, glyphCache[4].cacheMaximumCellSize);
1772 WLog_VRB(TAG,
"\tglyphCache5: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1773 glyphCache[5].cacheEntries, glyphCache[5].cacheMaximumCellSize);
1774 WLog_VRB(TAG,
"\tglyphCache6: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1775 glyphCache[6].cacheEntries, glyphCache[6].cacheMaximumCellSize);
1776 WLog_VRB(TAG,
"\tglyphCache7: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1777 glyphCache[7].cacheEntries, glyphCache[7].cacheMaximumCellSize);
1778 WLog_VRB(TAG,
"\tglyphCache8: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1779 glyphCache[8].cacheEntries, glyphCache[8].cacheMaximumCellSize);
1780 WLog_VRB(TAG,
"\tglyphCache9: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1781 glyphCache[9].cacheEntries, glyphCache[9].cacheMaximumCellSize);
1782 WLog_VRB(TAG,
"\tfragCache: Entries: %" PRIu16
" MaximumCellSize: %" PRIu16
"",
1783 fragCache.cacheEntries, fragCache.cacheMaximumCellSize);
1784 WLog_VRB(TAG,
"\tglyphSupportLevel: 0x%04" PRIX16
"", glyphSupportLevel);
1785 WLog_VRB(TAG,
"\tpad2Octets: 0x%04" PRIX16
"", pad2Octets);
1790 static BOOL rdp_apply_offscreen_bitmap_cache_capability_set(rdpSettings* settings,
1791 const rdpSettings* src)
1793 WINPR_ASSERT(settings);
1796 settings->OffscreenCacheSize = src->OffscreenCacheSize;
1797 settings->OffscreenCacheEntries = src->OffscreenCacheEntries;
1798 settings->OffscreenSupportLevel = src->OffscreenSupportLevel;
1808 static BOOL rdp_read_offscreen_bitmap_cache_capability_set(
wStream* s, rdpSettings* settings)
1810 UINT32 offscreenSupportLevel = 0;
1812 WINPR_ASSERT(settings);
1813 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1816 Stream_Read_UINT32(s, offscreenSupportLevel);
1817 Stream_Read_UINT16(s, settings->OffscreenCacheSize);
1818 Stream_Read_UINT16(s, settings->OffscreenCacheEntries);
1820 settings->OffscreenSupportLevel = offscreenSupportLevel & 0x01;
1830 static BOOL rdp_write_offscreen_bitmap_cache_capability_set(
wStream* s,
const rdpSettings* settings)
1832 UINT32 offscreenSupportLevel = 0x00;
1834 WINPR_ASSERT(settings);
1835 if (!Stream_EnsureRemainingCapacity(s, 32))
1838 const size_t header = rdp_capability_set_start(s);
1839 if (settings->OffscreenSupportLevel)
1841 offscreenSupportLevel = 0x01;
1842 Stream_Write_UINT32(s, offscreenSupportLevel);
1843 Stream_Write_UINT16(
1844 s, WINPR_ASSERTING_INT_CAST(
1845 uint16_t, settings->OffscreenCacheSize));
1846 Stream_Write_UINT16(
1848 WINPR_ASSERTING_INT_CAST(
1849 uint16_t, settings->OffscreenCacheEntries));
1854 return rdp_capability_set_finish(s, header, CAPSET_TYPE_OFFSCREEN_CACHE);
1857 #ifdef WITH_DEBUG_CAPABILITIES
1858 static BOOL rdp_print_offscreen_bitmap_cache_capability_set(
wStream* s)
1860 UINT32 offscreenSupportLevel = 0;
1861 UINT16 offscreenCacheSize = 0;
1862 UINT16 offscreenCacheEntries = 0;
1863 WLog_VRB(TAG,
"OffscreenBitmapCacheCapabilitySet (length %" PRIuz
"):",
1864 Stream_GetRemainingLength(s));
1866 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1869 Stream_Read_UINT32(s, offscreenSupportLevel);
1870 Stream_Read_UINT16(s, offscreenCacheSize);
1871 Stream_Read_UINT16(s, offscreenCacheEntries);
1872 WLog_VRB(TAG,
"\toffscreenSupportLevel: 0x%08" PRIX32
"", offscreenSupportLevel);
1873 WLog_VRB(TAG,
"\toffscreenCacheSize: 0x%04" PRIX16
"", offscreenCacheSize);
1874 WLog_VRB(TAG,
"\toffscreenCacheEntries: 0x%04" PRIX16
"", offscreenCacheEntries);
1879 static BOOL rdp_apply_bitmap_cache_host_support_capability_set(rdpSettings* settings,
1880 const rdpSettings* src)
1892 static BOOL rdp_read_bitmap_cache_host_support_capability_set(
wStream* s, rdpSettings* settings)
1894 BYTE cacheVersion = 0;
1896 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1899 Stream_Read_UINT8(s, cacheVersion);
1900 Stream_Seek_UINT8(s);
1901 Stream_Seek_UINT16(s);
1904 cacheVersion & BITMAP_CACHE_V2);
1912 static BOOL rdp_write_bitmap_cache_host_support_capability_set(
wStream* s,
1913 const rdpSettings* settings)
1915 UINT8 cacheVersion = 0;
1918 cacheVersion |= BITMAP_CACHE_V2;
1920 if (!Stream_EnsureRemainingCapacity(s, 32))
1923 const size_t header = rdp_capability_set_start(s);
1924 Stream_Write_UINT8(s, cacheVersion);
1925 Stream_Write_UINT8(s, 0);
1926 Stream_Write_UINT16(s, 0);
1927 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT);
1930 #ifdef WITH_DEBUG_CAPABILITIES
1931 static BOOL rdp_print_bitmap_cache_host_support_capability_set(
wStream* s)
1933 BYTE cacheVersion = 0;
1936 WLog_VRB(TAG,
"BitmapCacheHostSupportCapabilitySet (length %" PRIuz
"):",
1937 Stream_GetRemainingLength(s));
1939 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1942 Stream_Read_UINT8(s, cacheVersion);
1943 Stream_Read_UINT8(s, pad1);
1944 Stream_Read_UINT16(s, pad2);
1945 WLog_VRB(TAG,
"\tcacheVersion: 0x%02" PRIX8
"", cacheVersion);
1946 WLog_VRB(TAG,
"\tpad1: 0x%02" PRIX8
"", pad1);
1947 WLog_VRB(TAG,
"\tpad2: 0x%04" PRIX16
"", pad2);
1956 WINPR_ASSERT(cellInfo);
1957 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1964 Stream_Read_UINT32(s, info);
1965 cellInfo->numEntries = (info & 0x7FFFFFFF);
1966 cellInfo->persistent = (info & 0x80000000) ? 1 : 0;
1977 WINPR_ASSERT(cellInfo);
1978 info = (cellInfo->numEntries | (((UINT32)cellInfo->persistent << 31) & 0xFF000000));
1979 Stream_Write_UINT32(s, info);
1982 static BOOL rdp_apply_bitmap_cache_v2_capability_set(rdpSettings* settings,
const rdpSettings* src)
1984 const FreeRDP_Settings_Keys_Bool keys[] = { FreeRDP_BitmapCacheEnabled,
1985 FreeRDP_BitmapCachePersistEnabled };
1987 for (
size_t x = 0; x < ARRAYSIZE(keys); x++)
1989 const FreeRDP_Settings_Keys_Bool
id = keys[x];
1996 const UINT32 BitmapCacheV2NumCells =
1999 BitmapCacheV2NumCells))
2002 for (
size_t x = 0; x < BitmapCacheV2NumCells; x++)
2005 freerdp_settings_get_pointer_array(src, FreeRDP_BitmapCacheV2CellInfo, x);
2006 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_BitmapCacheV2CellInfo, x,
2020 static BOOL rdp_read_bitmap_cache_v2_capability_set(
wStream* s, rdpSettings* settings)
2022 UINT16 cacheFlags = 0;
2023 WINPR_UNUSED(settings);
2024 WINPR_ASSERT(settings);
2026 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2029 Stream_Read_UINT16(s, cacheFlags);
2034 cacheFlags & PERSISTENT_KEYS_EXPECTED_FLAG))
2037 Stream_Seek_UINT8(s);
2038 Stream_Read_UINT8(s, settings->BitmapCacheV2NumCells);
2039 if (settings->BitmapCacheV2NumCells > 5)
2041 WLog_ERR(TAG,
"Invalid TS_BITMAPCACHE_CAPABILITYSET_REV2::numCellCaches %" PRIu32
" > 5",
2042 settings->BitmapCacheV2NumCells);
2046 for (
size_t x = 0; x < settings->BitmapCacheV2NumCells; x++)
2049 freerdp_settings_get_pointer_array_writable(settings, FreeRDP_BitmapCacheV2CellInfo, x);
2050 if (!rdp_read_bitmap_cache_cell_info(s, info))
2055 for (
size_t x = settings->BitmapCacheV2NumCells; x < 5; x++)
2057 if (!Stream_SafeSeek(s, 4))
2069 static BOOL rdp_write_bitmap_cache_v2_capability_set(
wStream* s,
const rdpSettings* settings)
2071 WINPR_ASSERT(settings);
2072 if (!Stream_EnsureRemainingCapacity(s, 64))
2075 const size_t header = rdp_capability_set_start(s);
2076 UINT16 cacheFlags = ALLOW_CACHE_WAITING_LIST_FLAG;
2080 cacheFlags |= PERSISTENT_KEYS_EXPECTED_FLAG;
2081 settings->BitmapCacheV2CellInfo[0].persistent = 1;
2082 settings->BitmapCacheV2CellInfo[1].persistent = 1;
2083 settings->BitmapCacheV2CellInfo[2].persistent = 1;
2084 settings->BitmapCacheV2CellInfo[3].persistent = 1;
2085 settings->BitmapCacheV2CellInfo[4].persistent = 1;
2088 Stream_Write_UINT16(s, cacheFlags);
2089 Stream_Write_UINT8(s, 0);
2091 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2092 settings->BitmapCacheV2NumCells));
2093 rdp_write_bitmap_cache_cell_info(
2094 s, &settings->BitmapCacheV2CellInfo[0]);
2095 rdp_write_bitmap_cache_cell_info(
2096 s, &settings->BitmapCacheV2CellInfo[1]);
2097 rdp_write_bitmap_cache_cell_info(
2098 s, &settings->BitmapCacheV2CellInfo[2]);
2099 rdp_write_bitmap_cache_cell_info(
2100 s, &settings->BitmapCacheV2CellInfo[3]);
2101 rdp_write_bitmap_cache_cell_info(
2102 s, &settings->BitmapCacheV2CellInfo[4]);
2104 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V2);
2107 #ifdef WITH_DEBUG_CAPABILITIES
2108 static BOOL rdp_print_bitmap_cache_v2_capability_set(
wStream* s)
2111 WLog_VRB(TAG,
"BitmapCacheV2CapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2113 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2116 const UINT16 cacheFlags = Stream_Get_UINT16(s);
2117 const UINT8 pad2 = Stream_Get_UINT8(s);
2118 const UINT8 numCellCaches = Stream_Get_UINT8(s);
2120 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2122 if (!rdp_read_bitmap_cache_cell_info(
2123 s, &bitmapCacheV2CellInfo[x]))
2127 if (!Stream_SafeSeek(s, 12))
2130 WLog_VRB(TAG,
"\tcacheFlags: 0x%04" PRIX16
"", cacheFlags);
2131 WLog_VRB(TAG,
"\tpad2: 0x%02" PRIX8
"", pad2);
2132 WLog_VRB(TAG,
"\tnumCellCaches: 0x%02" PRIX8
"", numCellCaches);
2133 for (
size_t x = 0; x < ARRAYSIZE(bitmapCacheV2CellInfo); x++)
2137 "\tbitmapCache%" PRIuz
"CellInfo: numEntries: %" PRIu32
" persistent: %" PRId32
"",
2138 x, info->numEntries, info->persistent);
2144 static BOOL rdp_apply_virtual_channel_capability_set(rdpSettings* settings,
const rdpSettings* src)
2146 WINPR_ASSERT(settings);
2150 if (settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_SC) &&
2151 (src->VCFlags & VCCAPS_COMPR_SC))
2152 settings->VCFlags |= VCCAPS_COMPR_SC;
2154 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_SC;
2156 if (!settings->ServerMode && (settings->VCFlags & VCCAPS_COMPR_CS_8K) &&
2157 (src->VCFlags & VCCAPS_COMPR_CS_8K))
2158 settings->VCFlags |= VCCAPS_COMPR_CS_8K;
2160 settings->VCFlags &= (uint32_t)~VCCAPS_COMPR_CS_8K;
2167 if (!settings->ServerMode)
2169 if ((src->VCChunkSize > CHANNEL_CHUNK_MAX_LENGTH) || (src->VCChunkSize == 0))
2170 settings->VCChunkSize = CHANNEL_CHUNK_LENGTH;
2173 settings->VCChunkSize = src->VCChunkSize;
2185 static BOOL rdp_read_virtual_channel_capability_set(
wStream* s, rdpSettings* settings)
2188 UINT32 VCChunkSize = 0;
2190 WINPR_ASSERT(settings);
2191 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2194 Stream_Read_UINT32(s, flags);
2196 if (Stream_GetRemainingLength(s) >= 4)
2197 Stream_Read_UINT32(s, VCChunkSize);
2199 VCChunkSize = UINT32_MAX;
2201 settings->VCFlags = flags;
2202 settings->VCChunkSize = VCChunkSize;
2212 static BOOL rdp_write_virtual_channel_capability_set(
wStream* s,
const rdpSettings* settings)
2214 WINPR_ASSERT(settings);
2215 if (!Stream_EnsureRemainingCapacity(s, 32))
2218 const size_t header = rdp_capability_set_start(s);
2219 Stream_Write_UINT32(s, settings->VCFlags);
2220 Stream_Write_UINT32(s, settings->VCChunkSize);
2221 return rdp_capability_set_finish(s, header, CAPSET_TYPE_VIRTUAL_CHANNEL);
2224 #ifdef WITH_DEBUG_CAPABILITIES
2225 static BOOL rdp_print_virtual_channel_capability_set(
wStream* s)
2228 UINT32 VCChunkSize = 0;
2229 WLog_VRB(TAG,
"VirtualChannelCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2231 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2234 Stream_Read_UINT32(s, flags);
2236 if (Stream_GetRemainingLength(s) >= 4)
2237 Stream_Read_UINT32(s, VCChunkSize);
2241 WLog_VRB(TAG,
"\tflags: 0x%08" PRIX32
"", flags);
2242 WLog_VRB(TAG,
"\tVCChunkSize: 0x%08" PRIX32
"", VCChunkSize);
2247 static BOOL rdp_apply_draw_nine_grid_cache_capability_set(rdpSettings* settings,
2248 const rdpSettings* src)
2250 WINPR_ASSERT(settings);
2253 settings->DrawNineGridCacheSize = src->DrawNineGridCacheSize;
2254 settings->DrawNineGridCacheEntries = src->DrawNineGridCacheEntries;
2255 settings->DrawNineGridEnabled = src->DrawNineGridEnabled;
2265 static BOOL rdp_read_draw_nine_grid_cache_capability_set(
wStream* s, rdpSettings* settings)
2267 UINT32 drawNineGridSupportLevel = 0;
2269 WINPR_ASSERT(settings);
2270 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2273 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2274 Stream_Read_UINT16(s, settings->DrawNineGridCacheSize);
2275 Stream_Read_UINT16(s,
2276 settings->DrawNineGridCacheEntries);
2278 settings->DrawNineGridEnabled =
2279 (drawNineGridSupportLevel & (DRAW_NINEGRID_SUPPORTED | DRAW_NINEGRID_SUPPORTED_V2)) ? TRUE
2290 static BOOL rdp_write_draw_nine_grid_cache_capability_set(
wStream* s,
const rdpSettings* settings)
2292 WINPR_ASSERT(settings);
2293 if (!Stream_EnsureRemainingCapacity(s, 32))
2296 const size_t header = rdp_capability_set_start(s);
2297 const UINT32 drawNineGridSupportLevel =
2298 (settings->DrawNineGridEnabled) ? DRAW_NINEGRID_SUPPORTED_V2 : DRAW_NINEGRID_NO_SUPPORT;
2299 Stream_Write_UINT32(s, drawNineGridSupportLevel);
2300 Stream_Write_UINT16(
2301 s, WINPR_ASSERTING_INT_CAST(
2302 uint16_t, settings->DrawNineGridCacheSize));
2303 Stream_Write_UINT16(
2305 WINPR_ASSERTING_INT_CAST(
2306 uint16_t, settings->DrawNineGridCacheEntries));
2307 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_NINE_GRID_CACHE);
2310 static void rdp_write_gdiplus_cache_entries(
wStream* s, UINT16 gce, UINT16 bce, UINT16 pce,
2311 UINT16 ice, UINT16 ace)
2313 Stream_Write_UINT16(s, gce);
2314 Stream_Write_UINT16(s, bce);
2315 Stream_Write_UINT16(s, pce);
2316 Stream_Write_UINT16(s, ice);
2317 Stream_Write_UINT16(s, ace);
2320 static void rdp_write_gdiplus_cache_chunk_size(
wStream* s, UINT16 gccs, UINT16 obccs, UINT16 opccs,
2323 Stream_Write_UINT16(s, gccs);
2324 Stream_Write_UINT16(s, obccs);
2325 Stream_Write_UINT16(s, opccs);
2326 Stream_Write_UINT16(s, oiaccs);
2329 static void rdp_write_gdiplus_image_cache_properties(
wStream* s, UINT16 oiccs, UINT16 oicts,
2332 Stream_Write_UINT16(s, oiccs);
2333 Stream_Write_UINT16(s, oicts);
2334 Stream_Write_UINT16(s, oicms);
2337 #ifdef WITH_DEBUG_CAPABILITIES
2338 static BOOL rdp_print_draw_nine_grid_cache_capability_set(
wStream* s)
2340 UINT32 drawNineGridSupportLevel = 0;
2341 UINT16 DrawNineGridCacheSize = 0;
2342 UINT16 DrawNineGridCacheEntries = 0;
2344 "DrawNineGridCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2346 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2349 Stream_Read_UINT32(s, drawNineGridSupportLevel);
2350 Stream_Read_UINT16(s, DrawNineGridCacheSize);
2351 Stream_Read_UINT16(s, DrawNineGridCacheEntries);
2356 static BOOL rdp_apply_draw_gdiplus_cache_capability_set(rdpSettings* settings,
2357 const rdpSettings* src)
2359 WINPR_ASSERT(settings);
2362 if (src->DrawGdiPlusEnabled)
2363 settings->DrawGdiPlusEnabled = TRUE;
2365 if (src->DrawGdiPlusCacheEnabled)
2366 settings->DrawGdiPlusCacheEnabled = TRUE;
2376 static BOOL rdp_read_draw_gdiplus_cache_capability_set(
wStream* s, rdpSettings* settings)
2378 UINT32 drawGDIPlusSupportLevel = 0;
2379 UINT32 drawGdiplusCacheLevel = 0;
2381 WINPR_ASSERT(settings);
2382 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2385 Stream_Read_UINT32(s, drawGDIPlusSupportLevel);
2386 Stream_Seek_UINT32(s);
2387 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2392 settings->DrawGdiPlusEnabled =
2393 (drawGDIPlusSupportLevel & DRAW_GDIPLUS_SUPPORTED) ? TRUE : FALSE;
2394 settings->DrawGdiPlusCacheEnabled =
2395 (drawGdiplusCacheLevel & DRAW_GDIPLUS_CACHE_LEVEL_ONE) ? TRUE : FALSE;
2405 static BOOL rdp_write_draw_gdiplus_cache_capability_set(
wStream* s,
const rdpSettings* settings)
2407 WINPR_ASSERT(settings);
2408 if (!Stream_EnsureRemainingCapacity(s, 64))
2411 const size_t header = rdp_capability_set_start(s);
2412 const UINT32 drawGDIPlusSupportLevel =
2413 (settings->DrawGdiPlusEnabled) ? DRAW_GDIPLUS_SUPPORTED : DRAW_GDIPLUS_DEFAULT;
2414 const UINT32 drawGdiplusCacheLevel = (settings->DrawGdiPlusEnabled)
2415 ? DRAW_GDIPLUS_CACHE_LEVEL_ONE
2416 : DRAW_GDIPLUS_CACHE_LEVEL_DEFAULT;
2417 Stream_Write_UINT32(s, drawGDIPlusSupportLevel);
2418 Stream_Write_UINT32(s, 0);
2419 Stream_Write_UINT32(s, drawGdiplusCacheLevel);
2420 rdp_write_gdiplus_cache_entries(s, 10, 5, 5, 10, 2);
2421 rdp_write_gdiplus_cache_chunk_size(s, 512, 2048, 1024, 64);
2422 rdp_write_gdiplus_image_cache_properties(s, 4096, 256,
2424 return rdp_capability_set_finish(s, header, CAPSET_TYPE_DRAW_GDI_PLUS);
2427 #ifdef WITH_DEBUG_CAPABILITIES
2428 static BOOL rdp_print_draw_gdiplus_cache_capability_set(
wStream* s)
2430 UINT32 drawGdiPlusSupportLevel = 0;
2431 UINT32 GdipVersion = 0;
2432 UINT32 drawGdiplusCacheLevel = 0;
2434 "DrawGdiPlusCacheCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2436 if (!Stream_CheckAndLogRequiredLength(TAG, s, 36))
2439 Stream_Read_UINT32(s, drawGdiPlusSupportLevel);
2440 Stream_Read_UINT32(s, GdipVersion);
2441 Stream_Read_UINT32(s, drawGdiplusCacheLevel);
2449 static BOOL rdp_apply_remote_programs_capability_set(rdpSettings* settings,
const rdpSettings* src)
2451 WINPR_ASSERT(settings);
2454 if (settings->RemoteApplicationMode)
2455 settings->RemoteApplicationMode = src->RemoteApplicationMode;
2460 UINT32 supportLevel = src->RemoteApplicationSupportLevel;
2461 if (settings->RemoteApplicationMode)
2462 supportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2464 settings->RemoteApplicationSupportLevel = supportLevel & settings->RemoteApplicationSupportMask;
2474 static BOOL rdp_read_remote_programs_capability_set(
wStream* s, rdpSettings* settings)
2476 UINT32 railSupportLevel = 0;
2478 WINPR_ASSERT(settings);
2479 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2482 Stream_Read_UINT32(s, railSupportLevel);
2484 settings->RemoteApplicationMode = (railSupportLevel & RAIL_LEVEL_SUPPORTED) ? TRUE : FALSE;
2485 settings->RemoteApplicationSupportLevel = railSupportLevel;
2494 static BOOL rdp_write_remote_programs_capability_set(
wStream* s,
const rdpSettings* settings)
2496 WINPR_ASSERT(settings);
2497 if (!Stream_EnsureRemainingCapacity(s, 64))
2500 const size_t header = rdp_capability_set_start(s);
2501 UINT32 railSupportLevel = RAIL_LEVEL_SUPPORTED;
2503 if (settings->RemoteApplicationSupportLevel & RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED)
2505 if (settings->RemoteAppLanguageBarSupported)
2506 railSupportLevel |= RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED;
2509 railSupportLevel |= RAIL_LEVEL_SHELL_INTEGRATION_SUPPORTED;
2510 railSupportLevel |= RAIL_LEVEL_LANGUAGE_IME_SYNC_SUPPORTED;
2511 railSupportLevel |= RAIL_LEVEL_SERVER_TO_CLIENT_IME_SYNC_SUPPORTED;
2512 railSupportLevel |= RAIL_LEVEL_HIDE_MINIMIZED_APPS_SUPPORTED;
2513 railSupportLevel |= RAIL_LEVEL_WINDOW_CLOAKING_SUPPORTED;
2514 railSupportLevel |= RAIL_LEVEL_HANDSHAKE_EX_SUPPORTED;
2516 railSupportLevel &= settings->RemoteApplicationSupportLevel;
2517 Stream_Write_UINT32(s, railSupportLevel);
2518 return rdp_capability_set_finish(s, header, CAPSET_TYPE_RAIL);
2521 #ifdef WITH_DEBUG_CAPABILITIES
2522 static BOOL rdp_print_remote_programs_capability_set(
wStream* s)
2524 UINT32 railSupportLevel = 0;
2525 WLog_VRB(TAG,
"RemoteProgramsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2527 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2530 Stream_Read_UINT32(s, railSupportLevel);
2531 WLog_VRB(TAG,
"\trailSupportLevel: 0x%08" PRIX32
"", railSupportLevel);
2536 static BOOL rdp_apply_window_list_capability_set(rdpSettings* settings,
const rdpSettings* src)
2538 WINPR_ASSERT(settings);
2541 settings->RemoteWndSupportLevel = src->RemoteWndSupportLevel;
2542 settings->RemoteAppNumIconCaches = src->RemoteAppNumIconCaches;
2543 settings->RemoteAppNumIconCacheEntries = src->RemoteAppNumIconCacheEntries;
2553 static BOOL rdp_read_window_list_capability_set(
wStream* s, rdpSettings* settings)
2555 WINPR_ASSERT(settings);
2556 if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
2559 Stream_Read_UINT32(s, settings->RemoteWndSupportLevel);
2560 Stream_Read_UINT8(s, settings->RemoteAppNumIconCaches);
2561 Stream_Read_UINT16(s,
2562 settings->RemoteAppNumIconCacheEntries);
2571 static BOOL rdp_write_window_list_capability_set(
wStream* s,
const rdpSettings* settings)
2573 WINPR_ASSERT(settings);
2574 if (!Stream_EnsureRemainingCapacity(s, 32))
2577 const size_t header = rdp_capability_set_start(s);
2578 Stream_Write_UINT32(s, settings->RemoteWndSupportLevel);
2580 s, WINPR_ASSERTING_INT_CAST(uint8_t,
2581 settings->RemoteAppNumIconCaches));
2582 Stream_Write_UINT16(
2584 WINPR_ASSERTING_INT_CAST(
2585 uint16_t, settings->RemoteAppNumIconCacheEntries));
2586 return rdp_capability_set_finish(s, header, CAPSET_TYPE_WINDOW);
2589 #ifdef WITH_DEBUG_CAPABILITIES
2590 static BOOL rdp_print_window_list_capability_set(
wStream* s)
2592 UINT32 wndSupportLevel = 0;
2593 BYTE numIconCaches = 0;
2594 UINT16 numIconCacheEntries = 0;
2595 WLog_VRB(TAG,
"WindowListCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2597 if (!Stream_CheckAndLogRequiredLength(TAG, s, 7))
2600 Stream_Read_UINT32(s, wndSupportLevel);
2601 Stream_Read_UINT8(s, numIconCaches);
2602 Stream_Read_UINT16(s, numIconCacheEntries);
2603 WLog_VRB(TAG,
"\twndSupportLevel: 0x%08" PRIX32
"", wndSupportLevel);
2604 WLog_VRB(TAG,
"\tnumIconCaches: 0x%02" PRIX8
"", numIconCaches);
2605 WLog_VRB(TAG,
"\tnumIconCacheEntries: 0x%04" PRIX16
"", numIconCacheEntries);
2610 static BOOL rdp_apply_desktop_composition_capability_set(rdpSettings* settings,
2611 const rdpSettings* src)
2613 WINPR_ASSERT(settings);
2616 settings->CompDeskSupportLevel = src->CompDeskSupportLevel;
2625 static BOOL rdp_read_desktop_composition_capability_set(
wStream* s, rdpSettings* settings)
2627 WINPR_UNUSED(settings);
2628 WINPR_ASSERT(settings);
2630 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2633 Stream_Read_UINT16(s, settings->CompDeskSupportLevel);
2642 static BOOL rdp_write_desktop_composition_capability_set(
wStream* s,
const rdpSettings* settings)
2644 WINPR_ASSERT(settings);
2646 if (!Stream_EnsureRemainingCapacity(s, 32))
2649 const size_t header = rdp_capability_set_start(s);
2650 const UINT16 compDeskSupportLevel =
2651 (settings->AllowDesktopComposition) ? COMPDESK_SUPPORTED : COMPDESK_NOT_SUPPORTED;
2652 Stream_Write_UINT16(s, compDeskSupportLevel);
2653 return rdp_capability_set_finish(s, header, CAPSET_TYPE_COMP_DESK);
2656 #ifdef WITH_DEBUG_CAPABILITIES
2657 static BOOL rdp_print_desktop_composition_capability_set(
wStream* s)
2659 UINT16 compDeskSupportLevel = 0;
2661 "DesktopCompositionCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2663 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2666 Stream_Read_UINT16(s, compDeskSupportLevel);
2667 WLog_VRB(TAG,
"\tcompDeskSupportLevel: 0x%04" PRIX16
"", compDeskSupportLevel);
2672 static BOOL rdp_apply_multifragment_update_capability_set(rdpSettings* settings,
2673 const rdpSettings* src)
2675 UINT32 multifragMaxRequestSize = 0;
2677 WINPR_ASSERT(settings);
2680 multifragMaxRequestSize = src->MultifragMaxRequestSize;
2682 if (settings->ServerMode)
2692 if (multifragMaxRequestSize < FASTPATH_MAX_PACKET_SIZE)
2693 multifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
2695 if (settings->RemoteFxCodec)
2702 if (multifragMaxRequestSize < settings->MultifragMaxRequestSize)
2708 settings->RemoteFxCodec = FALSE;
2709 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2718 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2728 if (multifragMaxRequestSize > settings->MultifragMaxRequestSize)
2729 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2739 static BOOL rdp_read_multifragment_update_capability_set(
wStream* s, rdpSettings* settings)
2741 UINT32 multifragMaxRequestSize = 0;
2743 WINPR_ASSERT(settings);
2744 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2747 Stream_Read_UINT32(s, multifragMaxRequestSize);
2748 settings->MultifragMaxRequestSize = multifragMaxRequestSize;
2758 static BOOL rdp_write_multifragment_update_capability_set(
wStream* s, rdpSettings* settings)
2760 WINPR_ASSERT(settings);
2761 if (settings->ServerMode && settings->MultifragMaxRequestSize == 0)
2774 UINT32 tileNumX = (settings->DesktopWidth + 63) / 64;
2775 UINT32 tileNumY = (settings->DesktopHeight + 63) / 64;
2776 settings->MultifragMaxRequestSize = tileNumX * tileNumY * 16384;
2778 settings->MultifragMaxRequestSize += 16384;
2781 if (!Stream_EnsureRemainingCapacity(s, 32))
2783 const size_t header = rdp_capability_set_start(s);
2784 Stream_Write_UINT32(s, settings->MultifragMaxRequestSize);
2785 return rdp_capability_set_finish(s, header, CAPSET_TYPE_MULTI_FRAGMENT_UPDATE);
2788 #ifdef WITH_DEBUG_CAPABILITIES
2789 static BOOL rdp_print_multifragment_update_capability_set(
wStream* s)
2791 UINT32 maxRequestSize = 0;
2793 "MultifragmentUpdateCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2795 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
2798 Stream_Read_UINT32(s, maxRequestSize);
2799 WLog_VRB(TAG,
"\tmaxRequestSize: 0x%08" PRIX32
"", maxRequestSize);
2804 static BOOL rdp_apply_large_pointer_capability_set(rdpSettings* settings,
const rdpSettings* src)
2806 WINPR_ASSERT(settings);
2809 settings->LargePointerFlag = src->LargePointerFlag;
2818 static BOOL rdp_read_large_pointer_capability_set(
wStream* s, rdpSettings* settings)
2820 UINT16 largePointerSupportFlags = 0;
2822 WINPR_ASSERT(settings);
2823 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2826 Stream_Read_UINT16(s, largePointerSupportFlags);
2827 settings->LargePointerFlag &= largePointerSupportFlags;
2828 if ((largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384)) != 0)
2832 "TS_LARGE_POINTER_CAPABILITYSET with unsupported flags %04X (all flags %04X) received",
2833 largePointerSupportFlags & ~(LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384),
2834 largePointerSupportFlags);
2844 static BOOL rdp_write_large_pointer_capability_set(
wStream* s,
const rdpSettings* settings)
2846 WINPR_ASSERT(settings);
2847 if (!Stream_EnsureRemainingCapacity(s, 32))
2850 const size_t header = rdp_capability_set_start(s);
2851 const UINT16 largePointerSupportFlags =
2852 settings->LargePointerFlag & (LARGE_POINTER_FLAG_96x96 | LARGE_POINTER_FLAG_384x384);
2853 Stream_Write_UINT16(s, largePointerSupportFlags);
2854 return rdp_capability_set_finish(s, header, CAPSET_TYPE_LARGE_POINTER);
2857 #ifdef WITH_DEBUG_CAPABILITIES
2858 static BOOL rdp_print_large_pointer_capability_set(
wStream* s)
2860 UINT16 largePointerSupportFlags = 0;
2861 WLog_VRB(TAG,
"LargePointerCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2863 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
2866 Stream_Read_UINT16(s, largePointerSupportFlags);
2867 WLog_VRB(TAG,
"\tlargePointerSupportFlags: 0x%04" PRIX16
"", largePointerSupportFlags);
2872 static BOOL rdp_apply_surface_commands_capability_set(rdpSettings* settings,
const rdpSettings* src)
2874 WINPR_ASSERT(settings);
2881 if (src->FastPathOutput)
2883 settings->SurfaceCommandsSupported &= src->SurfaceCommandsSupported;
2884 settings->SurfaceCommandsEnabled = src->SurfaceCommandsEnabled;
2885 settings->SurfaceFrameMarkerEnabled = src->SurfaceFrameMarkerEnabled;
2889 settings->SurfaceCommandsSupported = 0;
2890 settings->SurfaceCommandsEnabled = FALSE;
2891 settings->SurfaceFrameMarkerEnabled = FALSE;
2902 static BOOL rdp_read_surface_commands_capability_set(
wStream* s, rdpSettings* settings)
2904 UINT32 cmdFlags = 0;
2906 WINPR_ASSERT(settings);
2907 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2910 Stream_Read_UINT32(s, cmdFlags);
2911 Stream_Seek_UINT32(s);
2912 settings->SurfaceCommandsSupported = cmdFlags;
2913 settings->SurfaceCommandsEnabled =
2914 (cmdFlags & (SURFCMDS_SET_SURFACE_BITS | SURFCMDS_STREAM_SURFACE_BITS)) ? TRUE : FALSE;
2915 settings->SurfaceFrameMarkerEnabled = (cmdFlags & SURFCMDS_FRAME_MARKER) ? TRUE : FALSE;
2924 static BOOL rdp_write_surface_commands_capability_set(
wStream* s,
const rdpSettings* settings)
2926 WINPR_ASSERT(settings);
2927 if (!Stream_EnsureRemainingCapacity(s, 32))
2930 const size_t header = rdp_capability_set_start(s);
2934 if (settings->SurfaceFrameMarkerEnabled)
2935 cmdFlags |= SURFCMDS_FRAME_MARKER;
2937 Stream_Write_UINT32(s, cmdFlags);
2938 Stream_Write_UINT32(s, 0);
2939 return rdp_capability_set_finish(s, header, CAPSET_TYPE_SURFACE_COMMANDS);
2942 #ifdef WITH_DEBUG_CAPABILITIES
2943 static BOOL rdp_print_surface_commands_capability_set(
wStream* s)
2945 UINT32 cmdFlags = 0;
2946 UINT32 reserved = 0;
2949 "SurfaceCommandsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
2951 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
2954 Stream_Read_UINT32(s, cmdFlags);
2955 Stream_Read_UINT32(s, reserved);
2956 WLog_VRB(TAG,
"\tcmdFlags: 0x%08" PRIX32
"", cmdFlags);
2957 WLog_VRB(TAG,
"\treserved: 0x%08" PRIX32
"", reserved);
2961 static void rdp_print_bitmap_codec_guid(
const GUID* guid)
2965 "%08" PRIX32
"%04" PRIX16
"%04" PRIX16
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
2966 "%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"%02" PRIX8
"",
2967 guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2],
2968 guid->Data4[3], guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
2971 static char* rdp_get_bitmap_codec_guid_name(
const GUID* guid)
2973 RPC_STATUS rpc_status = 0;
2976 if (UuidEqual(guid, &CODEC_GUID_REMOTEFX, &rpc_status))
2977 return "CODEC_GUID_REMOTEFX";
2978 else if (UuidEqual(guid, &CODEC_GUID_NSCODEC, &rpc_status))
2979 return "CODEC_GUID_NSCODEC";
2980 else if (UuidEqual(guid, &CODEC_GUID_IGNORE, &rpc_status))
2981 return "CODEC_GUID_IGNORE";
2982 else if (UuidEqual(guid, &CODEC_GUID_IMAGE_REMOTEFX, &rpc_status))
2983 return "CODEC_GUID_IMAGE_REMOTEFX";
2985 #if defined(WITH_JPEG)
2986 else if (UuidEqual(guid, &CODEC_GUID_JPEG, &rpc_status))
2987 return "CODEC_GUID_JPEG";
2990 return "CODEC_GUID_UNKNOWN";
2994 static BOOL rdp_read_bitmap_codec_guid(
wStream* s, GUID* guid)
2999 if (!Stream_CheckAndLogRequiredLength(TAG, s, 16))
3001 Stream_Read(s, g, 16);
3002 guid->Data1 = ((UINT32)g[3] << 24U) | ((UINT32)g[2] << 16U) | (UINT32)(g[1] << 8U) | g[0];
3003 guid->Data2 = ((g[5] << 8U) | g[4]) & 0xFFFF;
3004 guid->Data3 = ((g[7] << 8U) | g[6]) & 0xFFFF;
3005 guid->Data4[0] = g[8];
3006 guid->Data4[1] = g[9];
3007 guid->Data4[2] = g[10];
3008 guid->Data4[3] = g[11];
3009 guid->Data4[4] = g[12];
3010 guid->Data4[5] = g[13];
3011 guid->Data4[6] = g[14];
3012 guid->Data4[7] = g[15];
3016 static void rdp_write_bitmap_codec_guid(
wStream* s,
const GUID* guid)
3020 g[0] = guid->Data1 & 0xFF;
3021 g[1] = (guid->Data1 >> 8) & 0xFF;
3022 g[2] = (guid->Data1 >> 16) & 0xFF;
3023 g[3] = (guid->Data1 >> 24) & 0xFF;
3024 g[4] = (guid->Data2) & 0xFF;
3025 g[5] = (guid->Data2 >> 8) & 0xFF;
3026 g[6] = (guid->Data3) & 0xFF;
3027 g[7] = (guid->Data3 >> 8) & 0xFF;
3028 g[8] = guid->Data4[0];
3029 g[9] = guid->Data4[1];
3030 g[10] = guid->Data4[2];
3031 g[11] = guid->Data4[3];
3032 g[12] = guid->Data4[4];
3033 g[13] = guid->Data4[5];
3034 g[14] = guid->Data4[6];
3035 g[15] = guid->Data4[7];
3036 Stream_Write(s, g, 16);
3039 static BOOL rdp_apply_bitmap_codecs_capability_set(rdpSettings* settings,
const rdpSettings* src)
3041 WINPR_ASSERT(settings);
3044 if (settings->ServerMode)
3047 settings->RemoteFxCodecId = src->RemoteFxCodecId;
3048 settings->RemoteFxCaptureFlags = src->RemoteFxCaptureFlags;
3049 settings->RemoteFxOnly = src->RemoteFxOnly;
3050 settings->RemoteFxRlgrMode = src->RemoteFxRlgrMode;
3051 settings->RemoteFxCodecMode = src->RemoteFxCodecMode;
3052 settings->NSCodecId = src->NSCodecId;
3053 settings->NSCodecAllowDynamicColorFidelity = src->NSCodecAllowDynamicColorFidelity;
3054 settings->NSCodecAllowSubsampling = src->NSCodecAllowSubsampling;
3055 settings->NSCodecColorLossLevel = src->NSCodecColorLossLevel;
3058 settings->RemoteFxCodec = settings->RemoteFxCodec && src->RemoteFxCodecId;
3059 settings->RemoteFxImageCodec = settings->RemoteFxImageCodec && src->RemoteFxImageCodec;
3061 settings->NSCodec && src->NSCodec))
3063 settings->JpegCodec = src->JpegCodec;
3068 static BOOL rdp_read_codec_ts_rfx_icap(
wStream* sub, rdpSettings* settings, UINT16 icapLen)
3071 UINT16 tileSize = 0;
3072 BYTE codecFlags = 0;
3073 BYTE colConvBits = 0;
3074 BYTE transformBits = 0;
3075 BYTE entropyBits = 0;
3080 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP size %" PRIu16
3081 " unsupported, expecting size %" PRIu16
" not supported",
3086 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8))
3089 Stream_Read_UINT16(sub, version);
3090 Stream_Read_UINT16(sub, tileSize);
3091 Stream_Read_UINT8(sub, codecFlags);
3092 Stream_Read_UINT8(sub, colConvBits);
3093 Stream_Read_UINT8(sub, transformBits);
3094 Stream_Read_UINT8(sub, entropyBits);
3096 if (version == 0x0009)
3099 if (tileSize != 0x0080)
3102 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" tile size %" PRIu16
3108 else if (version == 0x0100)
3111 if (tileSize != 0x0040)
3114 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" tile size %" PRIu16
3122 WLog_ERR(TAG,
"[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::version %" PRIu16
" not supported",
3128 if (colConvBits != 1)
3131 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::colConvBits %" PRIu8
3132 " not supported, must be CLW_COL_CONV_ICT (0x1)",
3138 if (transformBits != 1)
3141 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::transformBits %" PRIu8
3142 " not supported, must be CLW_XFORM_DWT_53_A (0x1)",
3147 const UINT8 CODEC_MODE = 0x02;
3151 if ((codecFlags & CODEC_MODE) != 0)
3156 else if ((codecFlags & ~CODEC_MODE) != 0)
3158 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::flags unknown value "
3160 (codecFlags & ~CODEC_MODE));
3162 switch (entropyBits)
3164 case CLW_ENTROPY_RLGR1:
3168 case CLW_ENTROPY_RLGR3:
3174 "[MS-RDPRFX] 2.2.1.1.1.1.1 TS_RFX_ICAP::entropyBits "
3175 "unsupported value 0x%02" PRIx8
3176 ", must be CLW_ENTROPY_RLGR1 (0x01) or CLW_ENTROPY_RLGR3 "
3184 static BOOL rdp_read_codec_ts_rfx_capset(
wStream* s, rdpSettings* settings)
3186 UINT16 blockType = 0;
3187 UINT32 blockLen = 0;
3188 BYTE rfxCodecId = 0;
3189 UINT16 capsetType = 0;
3190 UINT16 numIcaps = 0;
3193 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
3197 Stream_Read_UINT16(s, blockType);
3198 Stream_Read_UINT32(s, blockLen);
3199 if (blockType != 0xCBC1)
3202 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockType[0x%04" PRIx16
3203 "] != CBY_CAPSET (0xCBC1)",
3207 if (blockLen < 6ull)
3209 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::blockLen[%" PRIu16
"] < 6", blockLen);
3212 if (!Stream_CheckAndLogRequiredLength(TAG, s, blockLen - 6ull))
3216 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), blockLen - 6ull);
3219 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 7))
3222 Stream_Read_UINT8(sub, rfxCodecId);
3223 Stream_Read_UINT16(sub, capsetType);
3224 Stream_Read_UINT16(sub, numIcaps);
3225 Stream_Read_UINT16(sub, icapLen);
3227 if (rfxCodecId != 1)
3229 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::codecId[%" PRIu16
"] != 1",
3234 if (capsetType != 0xCFC0)
3237 "[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::capsetType[0x%04" PRIx16
3238 "] != CLY_CAPSET (0xCFC0)",
3245 if (!rdp_read_codec_ts_rfx_icap(sub, settings, icapLen))
3251 static BOOL rdp_read_codec_ts_rfx_caps(
wStream* sub, rdpSettings* settings)
3253 if (Stream_GetRemainingLength(sub) == 0)
3256 UINT16 blockType = 0;
3257 UINT32 blockLen = 0;
3258 UINT16 numCapsets = 0;
3261 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8))
3263 Stream_Read_UINT16(sub, blockType);
3264 Stream_Read_UINT32(sub, blockLen);
3265 Stream_Read_UINT16(sub, numCapsets);
3267 if (blockType != 0xCBC0)
3270 "[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockType[0x%04" PRIx16
3271 "] != CBY_CAPS (0xCBC0)",
3278 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1 TS_RFX_CAPS::blockLen[%" PRIu16
"] != 8", blockLen);
3282 if (numCapsets != 1)
3284 WLog_ERR(TAG,
"[MS_RDPRFX] 2.2.1.1.1.1 TS_RFX_CAPSET::numIcaps[" PRIu16
"] != 1",
3289 for (UINT16 x = 0; x < numCapsets; x++)
3291 if (!rdp_read_codec_ts_rfx_capset(sub, settings))
3298 static BOOL rdp_read_codec_ts_rfx_clnt_caps_container(
wStream* s, rdpSettings* settings)
3300 UINT32 rfxCapsLength = 0;
3301 UINT32 rfxPropsLength = 0;
3302 UINT32 captureFlags = 0;
3305 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3307 Stream_Read_UINT32(s, rfxPropsLength);
3308 if (rfxPropsLength < 4)
3311 "[MS_RDPRFX] 2.2.1.1 TS_RFX_CLNT_CAPS_CONTAINER::length %" PRIu32
3312 " too short, require at least 4 bytes",
3316 if (!Stream_CheckAndLogRequiredLength(TAG, s, rfxPropsLength - 4ull))
3320 wStream* sub = Stream_StaticConstInit(&sbuffer, Stream_Pointer(s), rfxPropsLength - 4ull);
3323 Stream_Seek(s, rfxPropsLength - 4ull);
3325 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 8))
3328 Stream_Read_UINT32(sub, captureFlags);
3329 Stream_Read_UINT32(sub, rfxCapsLength);
3330 if (!Stream_CheckAndLogRequiredLength(TAG, sub, rfxCapsLength))
3333 settings->RemoteFxCaptureFlags = captureFlags;
3334 settings->RemoteFxOnly = (captureFlags & CARDP_CAPS_CAPTURE_NON_CAC) ? FALSE : TRUE;
3338 wStream* ts_sub = Stream_StaticConstInit(&tsbuffer, Stream_Pointer(sub), rfxCapsLength);
3339 WINPR_ASSERT(ts_sub);
3340 return rdp_read_codec_ts_rfx_caps(ts_sub, settings);
3348 static BOOL rdp_read_bitmap_codecs_capability_set(
wStream* s, rdpSettings* settings, BOOL isServer)
3351 GUID codecGuid = { 0 };
3352 RPC_STATUS rpc_status = 0;
3353 BYTE bitmapCodecCount = 0;
3354 UINT16 codecPropertiesLength = 0;
3356 BOOL guidNSCodec = FALSE;
3357 BOOL guidRemoteFx = FALSE;
3358 BOOL guidRemoteFxImage = FALSE;
3360 WINPR_ASSERT(settings);
3361 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3364 Stream_Read_UINT8(s, bitmapCodecCount);
3366 while (bitmapCodecCount > 0)
3370 if (!rdp_read_bitmap_codec_guid(s, &codecGuid))
3372 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
3374 Stream_Read_UINT8(s, codecId);
3375 Stream_Read_UINT16(s, codecPropertiesLength);
3377 wStream* sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), codecPropertiesLength);
3378 if (!Stream_SafeSeek(s, codecPropertiesLength))
3383 if (UuidEqual(&codecGuid, &CODEC_GUID_REMOTEFX, &rpc_status))
3385 guidRemoteFx = TRUE;
3386 settings->RemoteFxCodecId = codecId;
3387 if (!rdp_read_codec_ts_rfx_clnt_caps_container(sub, settings))
3390 else if (UuidEqual(&codecGuid, &CODEC_GUID_IMAGE_REMOTEFX, &rpc_status))
3393 guidRemoteFxImage = TRUE;
3394 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3397 else if (UuidEqual(&codecGuid, &CODEC_GUID_NSCODEC, &rpc_status))
3399 BYTE colorLossLevel = 0;
3400 BYTE fAllowSubsampling = 0;
3401 BYTE fAllowDynamicFidelity = 0;
3403 settings->NSCodecId = codecId;
3404 if (!Stream_CheckAndLogRequiredLength(TAG, sub, 3))
3406 Stream_Read_UINT8(sub, fAllowDynamicFidelity);
3407 Stream_Read_UINT8(sub, fAllowSubsampling);
3408 Stream_Read_UINT8(sub, colorLossLevel);
3410 if (colorLossLevel < 1)
3413 if (colorLossLevel > 7)
3416 settings->NSCodecAllowDynamicColorFidelity = fAllowDynamicFidelity;
3417 settings->NSCodecAllowSubsampling = fAllowSubsampling;
3418 settings->NSCodecColorLossLevel = colorLossLevel;
3420 else if (UuidEqual(&codecGuid, &CODEC_GUID_IGNORE, &rpc_status))
3422 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3427 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3433 if (!Stream_SafeSeek(sub, codecPropertiesLength))
3437 const size_t rest = Stream_GetRemainingLength(sub);
3441 "error while reading codec properties: actual size: %" PRIuz
3442 " expected size: %" PRIu32
"",
3443 rest + codecPropertiesLength, codecPropertiesLength);
3464 static BOOL rdp_write_rfx_client_capability_container(
wStream* s,
const rdpSettings* settings)
3466 WINPR_ASSERT(settings);
3467 if (!Stream_EnsureRemainingCapacity(s, 64))
3470 const UINT32 captureFlags = settings->RemoteFxOnly ? 0 : CARDP_CAPS_CAPTURE_NON_CAC;
3472 WINPR_ASSERT(settings->RemoteFxCodecMode <= UINT8_MAX);
3473 const UINT8 codecMode = (UINT8)settings->RemoteFxCodecMode;
3474 Stream_Write_UINT16(s, 49);
3476 Stream_Write_UINT32(s, 49);
3477 Stream_Write_UINT32(s, captureFlags);
3478 Stream_Write_UINT32(s, 37);
3480 Stream_Write_UINT16(s, CBY_CAPS);
3481 Stream_Write_UINT32(s, 8);
3482 Stream_Write_UINT16(s, 1);
3484 Stream_Write_UINT16(s, CBY_CAPSET);
3485 Stream_Write_UINT32(s, 29);
3486 Stream_Write_UINT8(s, 0x01);
3487 Stream_Write_UINT16(s, CLY_CAPSET);
3488 Stream_Write_UINT16(s, 2);
3489 Stream_Write_UINT16(s, 8);
3491 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3492 Stream_Write_UINT16(s, CT_TILE_64x64);
3493 Stream_Write_UINT8(s, codecMode);
3494 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3495 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3496 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR1);
3498 Stream_Write_UINT16(s, CLW_VERSION_1_0);
3499 Stream_Write_UINT16(s, CT_TILE_64x64);
3500 Stream_Write_UINT8(s, codecMode);
3501 Stream_Write_UINT8(s, CLW_COL_CONV_ICT);
3502 Stream_Write_UINT8(s, CLW_XFORM_DWT_53_A);
3503 Stream_Write_UINT8(s, CLW_ENTROPY_RLGR3);
3510 static BOOL rdp_write_nsc_client_capability_container(
wStream* s,
const rdpSettings* settings)
3512 WINPR_ASSERT(settings);
3514 const BOOL fAllowDynamicFidelity = settings->NSCodecAllowDynamicColorFidelity;
3515 const BOOL fAllowSubsampling = settings->NSCodecAllowSubsampling;
3516 UINT32 colorLossLevel = settings->NSCodecColorLossLevel;
3518 if (colorLossLevel < 1)
3521 if (colorLossLevel > 7)
3524 if (!Stream_EnsureRemainingCapacity(s, 8))
3527 Stream_Write_UINT16(s, 3);
3529 Stream_Write_UINT8(s,
3530 fAllowDynamicFidelity ? TRUE : FALSE);
3531 Stream_Write_UINT8(s, fAllowSubsampling ? TRUE : FALSE);
3532 Stream_Write_UINT8(s, (UINT8)colorLossLevel);
3536 #if defined(WITH_JPEG)
3537 static BOOL rdp_write_jpeg_client_capability_container(
wStream* s,
const rdpSettings* settings)
3539 WINPR_ASSERT(settings);
3540 if (!Stream_EnsureRemainingCapacity(s, 8))
3543 Stream_Write_UINT16(s, 1);
3544 Stream_Write_UINT8(s, settings->JpegQuality);
3552 static BOOL rdp_write_rfx_server_capability_container(
wStream* s,
const rdpSettings* settings)
3554 WINPR_UNUSED(settings);
3555 WINPR_ASSERT(settings);
3557 if (!Stream_EnsureRemainingCapacity(s, 8))
3560 Stream_Write_UINT16(s, 4);
3561 Stream_Write_UINT32(s, 0);
3565 static BOOL rdp_write_jpeg_server_capability_container(
wStream* s,
const rdpSettings* settings)
3567 WINPR_UNUSED(settings);
3568 WINPR_ASSERT(settings);
3570 if (!Stream_EnsureRemainingCapacity(s, 8))
3573 Stream_Write_UINT16(s, 1);
3574 Stream_Write_UINT8(s, 75);
3581 static BOOL rdp_write_nsc_server_capability_container(
wStream* s,
const rdpSettings* settings)
3583 WINPR_UNUSED(settings);
3584 WINPR_ASSERT(settings);
3586 if (!Stream_EnsureRemainingCapacity(s, 8))
3589 Stream_Write_UINT16(s, 4);
3590 Stream_Write_UINT32(s, 0);
3599 static BOOL rdp_write_bitmap_codecs_capability_set(
wStream* s,
const rdpSettings* settings)
3601 WINPR_ASSERT(settings);
3602 if (!Stream_EnsureRemainingCapacity(s, 64))
3605 const size_t header = rdp_capability_set_start(s);
3606 BYTE bitmapCodecCount = 0;
3608 if (settings->RemoteFxCodec)
3614 #if defined(WITH_JPEG)
3616 if (settings->JpegCodec)
3621 if (settings->RemoteFxImageCodec)
3624 Stream_Write_UINT8(s, bitmapCodecCount);
3626 if (settings->RemoteFxCodec)
3628 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_REMOTEFX);
3630 if (settings->ServerMode)
3632 Stream_Write_UINT8(s, 0);
3634 if (!rdp_write_rfx_server_capability_container(s, settings))
3639 Stream_Write_UINT8(s, RDP_CODEC_ID_REMOTEFX);
3641 if (!rdp_write_rfx_client_capability_container(s, settings))
3648 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_NSCODEC);
3650 if (settings->ServerMode)
3652 Stream_Write_UINT8(s, 0);
3654 if (!rdp_write_nsc_server_capability_container(s, settings))
3659 Stream_Write_UINT8(s, RDP_CODEC_ID_NSCODEC);
3661 if (!rdp_write_nsc_client_capability_container(s, settings))
3666 #if defined(WITH_JPEG)
3668 if (settings->JpegCodec)
3670 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_JPEG);
3672 if (settings->ServerMode)
3674 Stream_Write_UINT8(s, 0);
3676 if (!rdp_write_jpeg_server_capability_container(s, settings))
3681 Stream_Write_UINT8(s, RDP_CODEC_ID_JPEG);
3683 if (!rdp_write_jpeg_client_capability_container(s, settings))
3690 if (settings->RemoteFxImageCodec)
3692 rdp_write_bitmap_codec_guid(s, &CODEC_GUID_IMAGE_REMOTEFX);
3694 if (settings->ServerMode)
3696 Stream_Write_UINT8(s, 0);
3698 if (!rdp_write_rfx_server_capability_container(s, settings))
3703 Stream_Write_UINT8(s, RDP_CODEC_ID_IMAGE_REMOTEFX);
3705 if (!rdp_write_rfx_client_capability_container(s, settings))
3710 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CODECS);
3713 #ifdef WITH_DEBUG_CAPABILITIES
3714 static BOOL rdp_print_bitmap_codecs_capability_set(
wStream* s)
3716 GUID codecGuid = { 0 };
3717 BYTE bitmapCodecCount = 0;
3719 UINT16 codecPropertiesLength = 0;
3721 WLog_VRB(TAG,
"BitmapCodecsCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3723 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3726 Stream_Read_UINT8(s, bitmapCodecCount);
3727 WLog_VRB(TAG,
"\tbitmapCodecCount: %" PRIu8
"", bitmapCodecCount);
3729 while (bitmapCodecCount > 0)
3731 if (!rdp_read_bitmap_codec_guid(s, &codecGuid))
3733 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
3735 Stream_Read_UINT8(s, codecId);
3736 WLog_VRB(TAG,
"\tcodecGuid: 0x");
3737 rdp_print_bitmap_codec_guid(&codecGuid);
3738 WLog_VRB(TAG,
" (%s)", rdp_get_bitmap_codec_guid_name(&codecGuid));
3739 WLog_VRB(TAG,
"\tcodecId: %" PRIu8
"", codecId);
3740 Stream_Read_UINT16(s, codecPropertiesLength);
3741 WLog_VRB(TAG,
"\tcodecPropertiesLength: %" PRIu16
"", codecPropertiesLength);
3743 if (!Stream_SafeSeek(s, codecPropertiesLength))
3752 static BOOL rdp_apply_frame_acknowledge_capability_set(rdpSettings* settings,
3753 const rdpSettings* src)
3755 WINPR_ASSERT(settings);
3758 if (settings->ServerMode)
3759 settings->FrameAcknowledge = src->FrameAcknowledge;
3768 static BOOL rdp_read_frame_acknowledge_capability_set(
wStream* s, rdpSettings* settings)
3770 WINPR_ASSERT(settings);
3771 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3774 Stream_Read_UINT32(s, settings->FrameAcknowledge);
3783 static BOOL rdp_write_frame_acknowledge_capability_set(
wStream* s,
const rdpSettings* settings)
3785 WINPR_ASSERT(settings);
3786 if (!Stream_EnsureRemainingCapacity(s, 32))
3789 const size_t header = rdp_capability_set_start(s);
3790 Stream_Write_UINT32(s, settings->FrameAcknowledge);
3791 return rdp_capability_set_finish(s, header, CAPSET_TYPE_FRAME_ACKNOWLEDGE);
3794 #ifdef WITH_DEBUG_CAPABILITIES
3795 static BOOL rdp_print_frame_acknowledge_capability_set(
wStream* s)
3797 UINT32 frameAcknowledge = 0;
3799 "FrameAcknowledgeCapabilitySet (length %" PRIuz
"):", Stream_GetRemainingLength(s));
3801 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3804 Stream_Read_UINT32(s, frameAcknowledge);
3805 WLog_VRB(TAG,
"\tframeAcknowledge: 0x%08" PRIX32
"", frameAcknowledge);
3810 static BOOL rdp_apply_bitmap_cache_v3_codec_id_capability_set(rdpSettings* settings,
3811 const rdpSettings* src)
3813 WINPR_ASSERT(settings);
3816 settings->BitmapCacheV3CodecId = src->BitmapCacheV3CodecId;
3820 static BOOL rdp_read_bitmap_cache_v3_codec_id_capability_set(
wStream* s, rdpSettings* settings)
3822 BYTE bitmapCacheV3CodecId = 0;
3824 WINPR_ASSERT(settings);
3825 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3828 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3829 settings->BitmapCacheV3CodecId = bitmapCacheV3CodecId;
3833 static BOOL rdp_write_bitmap_cache_v3_codec_id_capability_set(
wStream* s,
3834 const rdpSettings* settings)
3836 WINPR_ASSERT(settings);
3837 if (!Stream_EnsureRemainingCapacity(s, 32))
3840 const size_t header = rdp_capability_set_start(s);
3841 if (settings->BitmapCacheV3CodecId > UINT8_MAX)
3843 Stream_Write_UINT8(s, (UINT8)settings->BitmapCacheV3CodecId);
3844 return rdp_capability_set_finish(s, header, CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID);
3847 #ifdef WITH_DEBUG_CAPABILITIES
3848 static BOOL rdp_print_bitmap_cache_v3_codec_id_capability_set(
wStream* s)
3850 BYTE bitmapCacheV3CodecId = 0;
3851 WLog_VRB(TAG,
"BitmapCacheV3CodecIdCapabilitySet (length %" PRIuz
"):",
3852 Stream_GetRemainingLength(s));
3854 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
3857 Stream_Read_UINT8(s, bitmapCacheV3CodecId);
3858 WLog_VRB(TAG,
"\tbitmapCacheV3CodecId: 0x%02" PRIX8
"", bitmapCacheV3CodecId);
3862 BOOL rdp_print_capability_sets(
wStream* s,
size_t start, BOOL receiving)
3867 UINT16 numberCapabilities = 0;
3869 size_t pos = Stream_GetPosition(s);
3871 Stream_SetPosition(s, start);
3874 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
3879 if (!Stream_CheckAndLogRequiredCapacity(TAG, (s), 4))
3883 Stream_Read_UINT16(s, numberCapabilities);
3886 while (numberCapabilities > 0)
3892 if (!rdp_read_capability_set_header(s, &length, &type))
3895 WLog_VRB(TAG,
"%s ", receiving ?
"Receiving" :
"Sending");
3896 sub = Stream_StaticInit(&subBuffer, Stream_Pointer(s), length - 4);
3897 if (!Stream_SafeSeek(s, length - 4))
3902 case CAPSET_TYPE_GENERAL:
3903 if (!rdp_print_general_capability_set(sub))
3908 case CAPSET_TYPE_BITMAP:
3909 if (!rdp_print_bitmap_capability_set(sub))
3914 case CAPSET_TYPE_ORDER:
3915 if (!rdp_print_order_capability_set(sub))
3920 case CAPSET_TYPE_BITMAP_CACHE:
3921 if (!rdp_print_bitmap_cache_capability_set(sub))
3926 case CAPSET_TYPE_CONTROL:
3927 if (!rdp_print_control_capability_set(sub))
3932 case CAPSET_TYPE_ACTIVATION:
3933 if (!rdp_print_window_activation_capability_set(sub))
3938 case CAPSET_TYPE_POINTER:
3939 if (!rdp_print_pointer_capability_set(sub))
3944 case CAPSET_TYPE_SHARE:
3945 if (!rdp_print_share_capability_set(sub))
3950 case CAPSET_TYPE_COLOR_CACHE:
3951 if (!rdp_print_color_cache_capability_set(sub))
3956 case CAPSET_TYPE_SOUND:
3957 if (!rdp_print_sound_capability_set(sub))
3962 case CAPSET_TYPE_INPUT:
3963 if (!rdp_print_input_capability_set(sub))
3968 case CAPSET_TYPE_FONT:
3969 if (!rdp_print_font_capability_set(sub))
3974 case CAPSET_TYPE_BRUSH:
3975 if (!rdp_print_brush_capability_set(sub))
3980 case CAPSET_TYPE_GLYPH_CACHE:
3981 if (!rdp_print_glyph_cache_capability_set(sub))
3986 case CAPSET_TYPE_OFFSCREEN_CACHE:
3987 if (!rdp_print_offscreen_bitmap_cache_capability_set(sub))
3992 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
3993 if (!rdp_print_bitmap_cache_host_support_capability_set(sub))
3998 case CAPSET_TYPE_BITMAP_CACHE_V2:
3999 if (!rdp_print_bitmap_cache_v2_capability_set(sub))
4004 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4005 if (!rdp_print_virtual_channel_capability_set(sub))
4010 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4011 if (!rdp_print_draw_nine_grid_cache_capability_set(sub))
4016 case CAPSET_TYPE_DRAW_GDI_PLUS:
4017 if (!rdp_print_draw_gdiplus_cache_capability_set(sub))
4022 case CAPSET_TYPE_RAIL:
4023 if (!rdp_print_remote_programs_capability_set(sub))
4028 case CAPSET_TYPE_WINDOW:
4029 if (!rdp_print_window_list_capability_set(sub))
4034 case CAPSET_TYPE_COMP_DESK:
4035 if (!rdp_print_desktop_composition_capability_set(sub))
4040 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4041 if (!rdp_print_multifragment_update_capability_set(sub))
4046 case CAPSET_TYPE_LARGE_POINTER:
4047 if (!rdp_print_large_pointer_capability_set(sub))
4052 case CAPSET_TYPE_SURFACE_COMMANDS:
4053 if (!rdp_print_surface_commands_capability_set(sub))
4058 case CAPSET_TYPE_BITMAP_CODECS:
4059 if (!rdp_print_bitmap_codecs_capability_set(sub))
4064 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4065 if (!rdp_print_frame_acknowledge_capability_set(sub))
4070 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4071 if (!rdp_print_bitmap_cache_v3_codec_id_capability_set(sub))
4077 WLog_ERR(TAG,
"unknown capability type %" PRIu16
"", type);
4081 rest = Stream_GetRemainingLength(sub);
4085 "incorrect capability offset, type:0x%04" PRIX16
" %" PRIu16
4086 " bytes expected, %" PRIuz
"bytes remaining",
4087 type, length, rest);
4090 numberCapabilities--;
4095 Stream_SetPosition(s, pos);
4100 static BOOL rdp_apply_from_received(UINT16 type, rdpSettings* dst,
const rdpSettings* src)
4104 case CAPSET_TYPE_GENERAL:
4105 return rdp_apply_general_capability_set(dst, src);
4106 case CAPSET_TYPE_BITMAP:
4107 return rdp_apply_bitmap_capability_set(dst, src);
4108 case CAPSET_TYPE_ORDER:
4109 return rdp_apply_order_capability_set(dst, src);
4110 case CAPSET_TYPE_POINTER:
4111 return rdp_apply_pointer_capability_set(dst, src);
4112 case CAPSET_TYPE_INPUT:
4113 return rdp_apply_input_capability_set(dst, src);
4114 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4115 return rdp_apply_virtual_channel_capability_set(dst, src);
4116 case CAPSET_TYPE_SHARE:
4117 return rdp_apply_share_capability_set(dst, src);
4118 case CAPSET_TYPE_COLOR_CACHE:
4119 return rdp_apply_color_cache_capability_set(dst, src);
4120 case CAPSET_TYPE_FONT:
4121 return rdp_apply_font_capability_set(dst, src);
4122 case CAPSET_TYPE_DRAW_GDI_PLUS:
4123 return rdp_apply_draw_gdiplus_cache_capability_set(dst, src);
4124 case CAPSET_TYPE_RAIL:
4125 return rdp_apply_remote_programs_capability_set(dst, src);
4126 case CAPSET_TYPE_WINDOW:
4127 return rdp_apply_window_list_capability_set(dst, src);
4128 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4129 return rdp_apply_multifragment_update_capability_set(dst, src);
4130 case CAPSET_TYPE_LARGE_POINTER:
4131 return rdp_apply_large_pointer_capability_set(dst, src);
4132 case CAPSET_TYPE_COMP_DESK:
4133 return rdp_apply_desktop_composition_capability_set(dst, src);
4134 case CAPSET_TYPE_SURFACE_COMMANDS:
4135 return rdp_apply_surface_commands_capability_set(dst, src);
4136 case CAPSET_TYPE_BITMAP_CODECS:
4137 return rdp_apply_bitmap_codecs_capability_set(dst, src);
4138 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4139 return rdp_apply_frame_acknowledge_capability_set(dst, src);
4140 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4141 return rdp_apply_bitmap_cache_v3_codec_id_capability_set(dst, src);
4142 case CAPSET_TYPE_BITMAP_CACHE:
4143 return rdp_apply_bitmap_cache_capability_set(dst, src);
4144 case CAPSET_TYPE_BITMAP_CACHE_V2:
4145 return rdp_apply_bitmap_cache_v2_capability_set(dst, src);
4146 case CAPSET_TYPE_BRUSH:
4147 return rdp_apply_brush_capability_set(dst, src);
4148 case CAPSET_TYPE_GLYPH_CACHE:
4149 return rdp_apply_glyph_cache_capability_set(dst, src);
4150 case CAPSET_TYPE_OFFSCREEN_CACHE:
4151 return rdp_apply_offscreen_bitmap_cache_capability_set(dst, src);
4152 case CAPSET_TYPE_SOUND:
4153 return rdp_apply_sound_capability_set(dst, src);
4154 case CAPSET_TYPE_CONTROL:
4155 return rdp_apply_control_capability_set(dst, src);
4156 case CAPSET_TYPE_ACTIVATION:
4157 return rdp_apply_window_activation_capability_set(dst, src);
4158 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4159 return rdp_apply_draw_nine_grid_cache_capability_set(dst, src);
4160 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4161 return rdp_apply_bitmap_cache_host_support_capability_set(dst, src);
4167 BOOL rdp_read_capability_set(
wStream* sub, UINT16 type, rdpSettings* settings, BOOL isServer)
4169 WINPR_ASSERT(settings);
4171 if (type <= CAPSET_TYPE_FRAME_ACKNOWLEDGE)
4173 const size_t size = Stream_Length(sub);
4174 if (size > UINT32_MAX)
4177 WINPR_ASSERT(settings->ReceivedCapabilities);
4178 settings->ReceivedCapabilities[type] = TRUE;
4180 WINPR_ASSERT(settings->ReceivedCapabilityDataSizes);
4181 settings->ReceivedCapabilityDataSizes[type] = (UINT32)size;
4183 WINPR_ASSERT(settings->ReceivedCapabilityData);
4184 void* tmp = realloc(settings->ReceivedCapabilityData[type], size);
4185 if (!tmp && (size > 0))
4187 memcpy(tmp, Stream_Buffer(sub), size);
4188 settings->ReceivedCapabilityData[type] = tmp;
4191 WLog_WARN(TAG,
"not handling capability type %" PRIu16
" yet", type);
4193 BOOL treated = TRUE;
4197 case CAPSET_TYPE_GENERAL:
4198 if (!rdp_read_general_capability_set(sub, settings))
4203 case CAPSET_TYPE_BITMAP:
4204 if (!rdp_read_bitmap_capability_set(sub, settings))
4209 case CAPSET_TYPE_ORDER:
4210 if (!rdp_read_order_capability_set(sub, settings))
4215 case CAPSET_TYPE_POINTER:
4216 if (!rdp_read_pointer_capability_set(sub, settings))
4221 case CAPSET_TYPE_INPUT:
4222 if (!rdp_read_input_capability_set(sub, settings))
4227 case CAPSET_TYPE_VIRTUAL_CHANNEL:
4228 if (!rdp_read_virtual_channel_capability_set(sub, settings))
4233 case CAPSET_TYPE_SHARE:
4234 if (!rdp_read_share_capability_set(sub, settings))
4239 case CAPSET_TYPE_COLOR_CACHE:
4240 if (!rdp_read_color_cache_capability_set(sub, settings))
4245 case CAPSET_TYPE_FONT:
4246 if (!rdp_read_font_capability_set(sub, settings))
4251 case CAPSET_TYPE_DRAW_GDI_PLUS:
4252 if (!rdp_read_draw_gdiplus_cache_capability_set(sub, settings))
4257 case CAPSET_TYPE_RAIL:
4258 if (!rdp_read_remote_programs_capability_set(sub, settings))
4263 case CAPSET_TYPE_WINDOW:
4264 if (!rdp_read_window_list_capability_set(sub, settings))
4269 case CAPSET_TYPE_MULTI_FRAGMENT_UPDATE:
4270 if (!rdp_read_multifragment_update_capability_set(sub, settings))
4275 case CAPSET_TYPE_LARGE_POINTER:
4276 if (!rdp_read_large_pointer_capability_set(sub, settings))
4281 case CAPSET_TYPE_COMP_DESK:
4282 if (!rdp_read_desktop_composition_capability_set(sub, settings))
4287 case CAPSET_TYPE_SURFACE_COMMANDS:
4288 if (!rdp_read_surface_commands_capability_set(sub, settings))
4293 case CAPSET_TYPE_BITMAP_CODECS:
4294 if (!rdp_read_bitmap_codecs_capability_set(sub, settings, isServer))
4299 case CAPSET_TYPE_FRAME_ACKNOWLEDGE:
4300 if (!rdp_read_frame_acknowledge_capability_set(sub, settings))
4305 case CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID:
4306 if (!rdp_read_bitmap_cache_v3_codec_id_capability_set(sub, settings))
4323 case CAPSET_TYPE_BITMAP_CACHE:
4324 if (!rdp_read_bitmap_cache_capability_set(sub, settings))
4329 case CAPSET_TYPE_BITMAP_CACHE_V2:
4330 if (!rdp_read_bitmap_cache_v2_capability_set(sub, settings))
4335 case CAPSET_TYPE_BRUSH:
4336 if (!rdp_read_brush_capability_set(sub, settings))
4341 case CAPSET_TYPE_GLYPH_CACHE:
4342 if (!rdp_read_glyph_cache_capability_set(sub, settings))
4347 case CAPSET_TYPE_OFFSCREEN_CACHE:
4348 if (!rdp_read_offscreen_bitmap_cache_capability_set(sub, settings))
4353 case CAPSET_TYPE_SOUND:
4354 if (!rdp_read_sound_capability_set(sub, settings))
4359 case CAPSET_TYPE_CONTROL:
4360 if (!rdp_read_control_capability_set(sub, settings))
4365 case CAPSET_TYPE_ACTIVATION:
4366 if (!rdp_read_window_activation_capability_set(sub, settings))
4371 case CAPSET_TYPE_DRAW_NINE_GRID_CACHE:
4372 if (!rdp_read_draw_nine_grid_cache_capability_set(sub, settings))
4378 WLog_ERR(TAG,
"capability %s(%" PRIu16
") not expected from client",
4379 get_capability_name(type), type);
4388 case CAPSET_TYPE_BITMAP_CACHE_HOST_SUPPORT:
4389 if (!rdp_read_bitmap_cache_host_support_capability_set(sub, settings))
4395 WLog_ERR(TAG,
"capability %s(%" PRIu16
") not expected from server",
4396 get_capability_name(type), type);
4402 const size_t rest = Stream_GetRemainingLength(sub);
4405 const size_t length = Stream_Capacity(sub);
4407 "incorrect offset, type:0x%04" PRIx16
" actual:%" PRIuz
" expected:%" PRIuz
"",
4408 type, length - rest, length);
4413 static BOOL rdp_read_capability_sets(
wStream* s, rdpSettings* settings, rdpSettings* rcvSettings,
4420 UINT16 numberCapabilities = 0;
4423 #ifdef WITH_DEBUG_CAPABILITIES
4424 const size_t capstart = Stream_GetPosition(s);
4428 WINPR_ASSERT(settings);
4430 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
4433 Stream_Read_UINT16(s, numberCapabilities);
4435 count = numberCapabilities;
4437 start = Stream_GetPosition(s);
4438 while (numberCapabilities > 0 && Stream_GetRemainingLength(s) >= 4)
4445 if (!rdp_read_capability_set_header(s, &length, &type))
4447 sub = Stream_StaticInit(&subbuffer, Stream_Pointer(s), length - 4);
4448 if (!Stream_SafeSeek(s, length - 4))
4451 if (!rdp_read_capability_set(sub, type, rcvSettings, settings->ServerMode))
4454 if (!rdp_apply_from_received(type, settings, rcvSettings))
4456 numberCapabilities--;
4459 end = Stream_GetPosition(s);
4462 if (numberCapabilities)
4465 "strange we haven't read the number of announced capacity sets, read=%d "
4466 "expected=%" PRIu16
"",
4467 count - numberCapabilities, count);
4470 #ifdef WITH_DEBUG_CAPABILITIES
4471 rdp_print_capability_sets(s, capstart, TRUE);
4474 if (len > totalLength)
4476 WLog_ERR(TAG,
"Capability length expected %" PRIu16
", actual %" PRIdz, totalLength, len);
4479 rc = freerdp_capability_buffer_copy(settings, rcvSettings);
4484 BOOL rdp_recv_get_active_header(rdpRdp* rdp,
wStream* s, UINT16* pChannelId, UINT16* length)
4487 WINPR_ASSERT(rdp->context);
4489 if (!rdp_read_header(rdp, s, length, pChannelId))
4492 if (freerdp_shall_disconnect_context(rdp->context))
4495 if (*pChannelId != MCS_GLOBAL_CHANNEL_ID)
4497 UINT16 mcsMessageChannelId = rdp->mcs->messageChannelId;
4499 if ((mcsMessageChannelId == 0) || (*pChannelId != mcsMessageChannelId))
4501 WLog_ERR(TAG,
"unexpected MCS channel id %04" PRIx16
" received", *pChannelId);
4509 BOOL rdp_recv_demand_active(rdpRdp* rdp,
wStream* s, UINT16 pduSource, UINT16 length)
4511 UINT16 lengthSourceDescriptor = 0;
4512 UINT16 lengthCombinedCapabilities = 0;
4515 WINPR_ASSERT(rdp->settings);
4516 WINPR_ASSERT(rdp->context);
4519 rdp->settings->PduSource = pduSource;
4521 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
4524 Stream_Read_UINT32(s, rdp->settings->ShareId);
4525 Stream_Read_UINT16(s, lengthSourceDescriptor);
4526 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4528 if (!Stream_SafeSeek(s, lengthSourceDescriptor) ||
4529 !Stream_CheckAndLogRequiredLength(TAG, s, 4))
4533 if (!rdp_read_capability_sets(s, rdp->settings, rdp->remoteSettings,
4534 lengthCombinedCapabilities))
4536 WLog_ERR(TAG,
"rdp_read_capability_sets failed");
4540 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
4543 UINT32 SessionId = 0;
4544 Stream_Read_UINT32(s, SessionId);
4548 secondary->glyph_v2 = (rdp->settings->GlyphSupportLevel > GLYPH_SUPPORT_FULL);
4551 return tpkt_ensure_stream_consumed(s, length);
4554 static BOOL rdp_write_demand_active(
wStream* s, rdpSettings* settings)
4559 UINT16 numberCapabilities = 0;
4560 size_t lengthCombinedCapabilities = 0;
4562 if (!Stream_EnsureRemainingCapacity(s, 64))
4565 Stream_Write_UINT32(s, settings->ShareId);
4566 Stream_Write_UINT16(s, 4);
4567 lm = Stream_GetPosition(s);
4568 Stream_Seek_UINT16(s);
4569 Stream_Write(s,
"RDP", 4);
4570 bm = Stream_GetPosition(s);
4571 Stream_Seek_UINT16(s);
4572 Stream_Write_UINT16(s, 0);
4573 numberCapabilities = 14;
4575 if (!rdp_write_general_capability_set(s, settings) ||
4576 !rdp_write_bitmap_capability_set(s, settings) ||
4577 !rdp_write_order_capability_set(s, settings) ||
4578 !rdp_write_pointer_capability_set(s, settings) ||
4579 !rdp_write_input_capability_set(s, settings) ||
4580 !rdp_write_virtual_channel_capability_set(s, settings) ||
4581 !rdp_write_share_capability_set(s, settings) ||
4582 !rdp_write_font_capability_set(s, settings) ||
4583 !rdp_write_multifragment_update_capability_set(s, settings) ||
4584 !rdp_write_large_pointer_capability_set(s, settings) ||
4585 !rdp_write_desktop_composition_capability_set(s, settings) ||
4586 !rdp_write_surface_commands_capability_set(s, settings) ||
4587 !rdp_write_bitmap_codecs_capability_set(s, settings) ||
4588 !rdp_write_frame_acknowledge_capability_set(s, settings))
4595 numberCapabilities++;
4597 if (!rdp_write_bitmap_cache_host_support_capability_set(s, settings))
4601 if (settings->RemoteApplicationMode)
4603 numberCapabilities += 2;
4605 if (!rdp_write_remote_programs_capability_set(s, settings) ||
4606 !rdp_write_window_list_capability_set(s, settings))
4610 em = Stream_GetPosition(s);
4611 Stream_SetPosition(s, lm);
4612 lengthCombinedCapabilities = (em - bm);
4613 if (lengthCombinedCapabilities > UINT16_MAX)
4615 Stream_Write_UINT16(
4616 s, (UINT16)lengthCombinedCapabilities);
4617 Stream_SetPosition(s, bm);
4618 Stream_Write_UINT16(s, numberCapabilities);
4619 #ifdef WITH_DEBUG_CAPABILITIES
4620 rdp_print_capability_sets(s, bm, FALSE);
4622 Stream_SetPosition(s, em);
4623 Stream_Write_UINT32(s, 0);
4627 BOOL rdp_send_demand_active(rdpRdp* rdp)
4629 wStream* s = rdp_send_stream_pdu_init(rdp);
4635 rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
4636 status = rdp_write_demand_active(s, rdp->settings) &&
4637 rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId);
4642 BOOL rdp_recv_confirm_active(rdpRdp* rdp,
wStream* s, UINT16 pduLength)
4644 rdpSettings* settings = NULL;
4645 UINT16 lengthSourceDescriptor = 0;
4646 UINT16 lengthCombinedCapabilities = 0;
4650 settings = rdp->settings;
4651 WINPR_ASSERT(settings);
4653 if (!Stream_CheckAndLogRequiredLength(TAG, s, 10))
4656 Stream_Seek_UINT32(s);
4657 Stream_Seek_UINT16(s);
4658 Stream_Read_UINT16(s, lengthSourceDescriptor);
4659 Stream_Read_UINT16(s, lengthCombinedCapabilities);
4661 if (!Stream_CheckAndLogRequiredLength(TAG, s, lengthSourceDescriptor + 4U))
4664 Stream_Seek(s, lengthSourceDescriptor);
4665 if (!rdp_read_capability_sets(s, rdp->settings, rdp->remoteSettings,
4666 lengthCombinedCapabilities))
4669 if (!settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4672 settings->SurfaceCommandsEnabled = FALSE;
4673 settings->SurfaceFrameMarkerEnabled = FALSE;
4676 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4679 settings->FrameAcknowledge = 0;
4682 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4685 settings->BitmapCacheV3Enabled = FALSE;
4688 if (!settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4699 if (!settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4702 settings->MultifragMaxRequestSize = FASTPATH_FRAGMENT_SAFE_SIZE;
4705 if (!settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4708 settings->LargePointerFlag = 0;
4711 return tpkt_ensure_stream_consumed(s, pduLength);
4714 static BOOL rdp_write_confirm_active(
wStream* s, rdpSettings* settings)
4719 UINT16 numberCapabilities = 0;
4720 UINT16 lengthSourceDescriptor = 0;
4721 size_t lengthCombinedCapabilities = 0;
4724 WINPR_ASSERT(settings);
4726 lengthSourceDescriptor =
sizeof(SOURCE_DESCRIPTOR);
4727 Stream_Write_UINT32(s, settings->ShareId);
4728 Stream_Write_UINT16(s, 0x03EA);
4729 Stream_Write_UINT16(s, lengthSourceDescriptor);
4730 lm = Stream_GetPosition(s);
4731 Stream_Seek_UINT16(s);
4732 Stream_Write(s, SOURCE_DESCRIPTOR, lengthSourceDescriptor);
4733 bm = Stream_GetPosition(s);
4734 Stream_Seek_UINT16(s);
4735 Stream_Write_UINT16(s, 0);
4737 numberCapabilities = 15;
4739 if (!rdp_write_general_capability_set(s, settings) ||
4740 !rdp_write_bitmap_capability_set(s, settings) ||
4741 !rdp_write_order_capability_set(s, settings))
4744 if (settings->RdpVersion >= RDP_VERSION_5_PLUS)
4745 ret = rdp_write_bitmap_cache_v2_capability_set(s, settings);
4747 ret = rdp_write_bitmap_cache_capability_set(s, settings);
4752 if (!rdp_write_pointer_capability_set(s, settings) ||
4753 !rdp_write_input_capability_set(s, settings) ||
4754 !rdp_write_brush_capability_set(s, settings) ||
4755 !rdp_write_glyph_cache_capability_set(s, settings) ||
4756 !rdp_write_virtual_channel_capability_set(s, settings) ||
4757 !rdp_write_sound_capability_set(s, settings) ||
4758 !rdp_write_share_capability_set(s, settings) ||
4759 !rdp_write_font_capability_set(s, settings) ||
4760 !rdp_write_control_capability_set(s, settings) ||
4761 !rdp_write_color_cache_capability_set(s, settings) ||
4762 !rdp_write_window_activation_capability_set(s, settings))
4767 if (settings->OffscreenSupportLevel)
4769 numberCapabilities++;
4771 if (!rdp_write_offscreen_bitmap_cache_capability_set(s, settings))
4775 if (settings->DrawNineGridEnabled)
4777 numberCapabilities++;
4779 if (!rdp_write_draw_nine_grid_cache_capability_set(s, settings))
4783 if (settings->ReceivedCapabilities[CAPSET_TYPE_LARGE_POINTER])
4785 if (settings->LargePointerFlag)
4787 numberCapabilities++;
4789 if (!rdp_write_large_pointer_capability_set(s, settings))
4794 if (settings->RemoteApplicationMode)
4796 numberCapabilities += 2;
4798 if (!rdp_write_remote_programs_capability_set(s, settings) ||
4799 !rdp_write_window_list_capability_set(s, settings))
4803 if (settings->ReceivedCapabilities[CAPSET_TYPE_MULTI_FRAGMENT_UPDATE])
4805 numberCapabilities++;
4807 if (!rdp_write_multifragment_update_capability_set(s, settings))
4811 if (settings->ReceivedCapabilities[CAPSET_TYPE_SURFACE_COMMANDS])
4813 numberCapabilities++;
4815 if (!rdp_write_surface_commands_capability_set(s, settings))
4819 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CODECS])
4821 numberCapabilities++;
4823 if (!rdp_write_bitmap_codecs_capability_set(s, settings))
4827 if (!settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
4828 settings->FrameAcknowledge = 0;
4830 if (settings->FrameAcknowledge)
4832 numberCapabilities++;
4834 if (!rdp_write_frame_acknowledge_capability_set(s, settings))
4838 if (settings->ReceivedCapabilities[CAPSET_TYPE_BITMAP_CACHE_V3_CODEC_ID])
4840 if (settings->BitmapCacheV3CodecId != 0)
4842 numberCapabilities++;
4844 if (!rdp_write_bitmap_cache_v3_codec_id_capability_set(s, settings))
4849 em = Stream_GetPosition(s);
4850 Stream_SetPosition(s, lm);
4851 lengthCombinedCapabilities = (em - bm);
4852 if (lengthCombinedCapabilities > UINT16_MAX)
4854 Stream_Write_UINT16(
4855 s, (UINT16)lengthCombinedCapabilities);
4856 Stream_SetPosition(s, bm);
4857 Stream_Write_UINT16(s, numberCapabilities);
4858 #ifdef WITH_DEBUG_CAPABILITIES
4859 rdp_print_capability_sets(s, bm, FALSE);
4861 Stream_SetPosition(s, em);
4866 BOOL rdp_send_confirm_active(rdpRdp* rdp)
4868 wStream* s = rdp_send_stream_pdu_init(rdp);
4874 status = rdp_write_confirm_active(s, rdp->settings) &&
4875 rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId);
4880 const char* rdp_input_flag_string(UINT16 flags,
char* buffer,
size_t len)
4882 char prefix[16] = { 0 };
4884 (void)_snprintf(prefix,
sizeof(prefix),
"[0x%04" PRIx16
"][", flags);
4885 winpr_str_append(prefix, buffer, len,
"");
4886 if ((flags & INPUT_FLAG_SCANCODES) != 0)
4887 winpr_str_append(
"INPUT_FLAG_SCANCODES", buffer, len,
"|");
4888 if ((flags & INPUT_FLAG_MOUSEX) != 0)
4889 winpr_str_append(
"INPUT_FLAG_MOUSEX", buffer, len,
"|");
4890 if ((flags & INPUT_FLAG_FASTPATH_INPUT) != 0)
4891 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT", buffer, len,
"|");
4892 if ((flags & INPUT_FLAG_UNICODE) != 0)
4893 winpr_str_append(
"INPUT_FLAG_UNICODE", buffer, len,
"|");
4894 if ((flags & INPUT_FLAG_FASTPATH_INPUT2) != 0)
4895 winpr_str_append(
"INPUT_FLAG_FASTPATH_INPUT2", buffer, len,
"|");
4896 if ((flags & INPUT_FLAG_UNUSED1) != 0)
4897 winpr_str_append(
"INPUT_FLAG_UNUSED1", buffer, len,
"|");
4898 if ((flags & INPUT_FLAG_MOUSE_RELATIVE) != 0)
4899 winpr_str_append(
"INPUT_FLAG_MOUSE_RELATIVE", buffer, len,
"|");
4900 if ((flags & TS_INPUT_FLAG_MOUSE_HWHEEL) != 0)
4901 winpr_str_append(
"TS_INPUT_FLAG_MOUSE_HWHEEL", buffer, len,
"|");
4902 if ((flags & TS_INPUT_FLAG_QOE_TIMESTAMPS) != 0)
4903 winpr_str_append(
"TS_INPUT_FLAG_QOE_TIMESTAMPS", buffer, len,
"|");
4904 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.