21#include <freerdp/config.h>
26#include <winpr/assert.h>
28#include <freerdp/log.h>
32#define TAG FREERDP_TAG("core.window")
34static void update_free_window_icon_info(
ICON_INFO* iconInfo);
38 WINPR_ASSERT(unicode_string);
40 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
43 const UINT16 new_len = Stream_Get_UINT16(s);
45 if (!Stream_CheckAndLogRequiredLength(TAG, s, new_len))
48 if ((new_len == 0) || ((new_len %
sizeof(WCHAR)) != 0))
50 rail_unicode_string_free(unicode_string);
54 WCHAR* new_str = realloc(unicode_string->string, new_len);
57 rail_unicode_string_free(unicode_string);
61 unicode_string->string = new_str;
62 unicode_string->length = new_len;
63 Stream_Read(s, unicode_string->string, unicode_string->length);
64 if (_wcsnlen(unicode_string->string, unicode_string->length) != unicode_string->length)
66 WLog_ERR(TAG,
"Failed to read UNICODE_STRING, data contains \\0 characters!");
74 if (!s || !unicode_string)
75 return ERROR_INVALID_PARAMETER;
77 const size_t length = unicode_string->length;
78 WINPR_ASSERT((length %
sizeof(WCHAR)) == 0);
81 if (!Stream_EnsureRemainingCapacity(s, length))
83 WLog_ERR(TAG,
"Stream_EnsureRemainingCapacity failed!");
84 return CHANNEL_RC_NO_MEMORY;
87 Stream_Write(s, unicode_string->string, length);
95 if (!s || !unicode_string)
96 return ERROR_INVALID_PARAMETER;
98 if (!Stream_EnsureRemainingCapacity(s, 2 + unicode_string->length))
100 WLog_ERR(TAG,
"Stream_EnsureRemainingCapacity failed!");
101 return CHANNEL_RC_NO_MEMORY;
104 Stream_Write_UINT16(s, unicode_string->length);
105 return rail_write_unicode_string_value(s, unicode_string);
110 WINPR_ASSERT(unicode_string);
111 free(unicode_string->string);
112 unicode_string->string =
nullptr;
113 unicode_string->length = 0;
118 WINPR_ASSERT(unicode_string);
120 rail_unicode_string_free(unicode_string);
122 if (!
string || strlen(
string) < 1)
126 WCHAR* buffer = ConvertUtf8ToWCharAlloc(
string, &len);
128 const size_t wlen = len *
sizeof(WCHAR);
129 if (!buffer || (wlen > UINT16_MAX))
135 unicode_string->string = buffer;
136 unicode_string->length = WINPR_ASSERTING_INT_CAST(UINT16, len *
sizeof(WCHAR));
142 WINPR_ASSERT(unicode_string);
143 WINPR_ASSERT((unicode_string->length %
sizeof(WCHAR)) == 0);
144 WINPR_ASSERT(((unicode_string->length > 0) && (unicode_string->string)) ||
145 (unicode_string->length == 0));
148 size_t inLen = unicode_string->length /
sizeof(WCHAR);
149 return ConvertWCharNToUtf8Alloc(unicode_string->string, inLen, &outLen);
155 BYTE* newBitMask =
nullptr;
157 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
160 Stream_Read_UINT16(s, iconInfo->cacheEntry);
161 Stream_Read_UINT8(s, iconInfo->cacheId);
162 Stream_Read_UINT8(s, iconInfo->bpp);
164 if ((iconInfo->bpp < 1) || (iconInfo->bpp > 32))
166 WLog_ERR(TAG,
"invalid bpp value %" PRIu32
"", iconInfo->bpp);
170 Stream_Read_UINT16(s, iconInfo->width);
171 Stream_Read_UINT16(s, iconInfo->height);
174 switch (iconInfo->bpp)
179 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
182 Stream_Read_UINT16(s, iconInfo->cbColorTable);
186 iconInfo->cbColorTable = 0;
190 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
193 Stream_Read_UINT16(s, iconInfo->cbBitsMask);
194 Stream_Read_UINT16(s, iconInfo->cbBitsColor);
197 if (iconInfo->cbBitsMask > 0)
199 newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);
203 free(iconInfo->bitsMask);
204 iconInfo->bitsMask =
nullptr;
208 iconInfo->bitsMask = newBitMask;
209 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsMask))
211 Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);
215 free(iconInfo->bitsMask);
216 iconInfo->bitsMask =
nullptr;
217 iconInfo->cbBitsMask = 0;
221 if (iconInfo->cbColorTable > 0)
223 BYTE* new_tab =
nullptr;
224 new_tab = (BYTE*)realloc(iconInfo->colorTable, iconInfo->cbColorTable);
228 free(iconInfo->colorTable);
229 iconInfo->colorTable =
nullptr;
233 iconInfo->colorTable = new_tab;
237 free(iconInfo->colorTable);
238 iconInfo->colorTable =
nullptr;
241 if (iconInfo->colorTable)
243 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbColorTable))
245 Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable);
249 if (iconInfo->cbBitsColor > 0)
251 newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor);
255 free(iconInfo->bitsColor);
256 iconInfo->bitsColor =
nullptr;
260 iconInfo->bitsColor = newBitMask;
261 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsColor))
263 Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor);
267 free(iconInfo->bitsColor);
268 iconInfo->bitsColor =
nullptr;
269 iconInfo->cbBitsColor = 0;
276 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
279 Stream_Read_UINT16(s, cachedIconInfo->cacheEntry);
280 Stream_Read_UINT8(s, cachedIconInfo->cacheId);
286 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
289 Stream_Read_UINT32(s, notifyIconInfoTip->timeout);
290 Stream_Read_UINT32(s, notifyIconInfoTip->flags);
291 return rail_read_unicode_string(s, ¬ifyIconInfoTip->text) &&
292 rail_read_unicode_string(s, ¬ifyIconInfoTip->title);
301 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
303 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
306 Stream_Read_UINT32(s, windowState->ownerWindowId);
309 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
311 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
314 Stream_Read_UINT32(s, windowState->style);
315 Stream_Read_UINT32(s, windowState->extendedStyle);
318 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
320 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
323 Stream_Read_UINT8(s, windowState->showState);
326 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
328 if (!rail_read_unicode_string(s, &windowState->titleInfo))
332 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
334 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
337 Stream_Read_INT32(s, windowState->clientOffsetX);
338 Stream_Read_INT32(s, windowState->clientOffsetY);
341 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
343 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
346 Stream_Read_UINT32(s, windowState->clientAreaWidth);
347 Stream_Read_UINT32(s, windowState->clientAreaHeight);
350 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
352 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
355 Stream_Read_UINT32(s, windowState->resizeMarginLeft);
356 Stream_Read_UINT32(s, windowState->resizeMarginRight);
359 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
361 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
364 Stream_Read_UINT32(s, windowState->resizeMarginTop);
365 Stream_Read_UINT32(s, windowState->resizeMarginBottom);
368 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
370 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
373 Stream_Read_UINT8(s, windowState->RPContent);
376 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
378 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
381 Stream_Read_UINT32(s, windowState->rootParentHandle);
384 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
386 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
389 Stream_Read_INT32(s, windowState->windowOffsetX);
390 Stream_Read_INT32(s, windowState->windowOffsetY);
393 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
395 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
398 Stream_Read_INT32(s, windowState->windowClientDeltaX);
399 Stream_Read_INT32(s, windowState->windowClientDeltaY);
402 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
404 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
407 Stream_Read_UINT32(s, windowState->windowWidth);
408 Stream_Read_UINT32(s, windowState->windowHeight);
411 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
413 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
416 Stream_Read_UINT16(s, windowState->numWindowRects);
418 if (windowState->numWindowRects > 0)
420 size =
sizeof(
RECTANGLE_16) * windowState->numWindowRects;
421 newRect = (
RECTANGLE_16*)realloc(windowState->windowRects, size);
425 free(windowState->windowRects);
426 windowState->windowRects =
nullptr;
430 windowState->windowRects = newRect;
432 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numWindowRects, 8ull))
436 for (UINT32 i = 0; i < windowState->numWindowRects; i++)
438 Stream_Read_UINT16(s, windowState->windowRects[i].left);
439 Stream_Read_UINT16(s, windowState->windowRects[i].top);
440 Stream_Read_UINT16(s, windowState->windowRects[i].right);
441 Stream_Read_UINT16(s, windowState->windowRects[i].bottom);
446 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
448 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
451 Stream_Read_INT32(s, windowState->visibleOffsetX);
452 Stream_Read_INT32(s, windowState->visibleOffsetY);
455 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
457 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
460 Stream_Read_UINT16(s, windowState->numVisibilityRects);
462 if (windowState->numVisibilityRects != 0)
464 size =
sizeof(
RECTANGLE_16) * windowState->numVisibilityRects;
465 newRect = (
RECTANGLE_16*)realloc(windowState->visibilityRects, size);
469 free(windowState->visibilityRects);
470 windowState->visibilityRects =
nullptr;
474 windowState->visibilityRects = newRect;
476 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numVisibilityRects,
481 for (UINT32 i = 0; i < windowState->numVisibilityRects; i++)
483 Stream_Read_UINT16(s, windowState->visibilityRects[i].left);
484 Stream_Read_UINT16(s, windowState->visibilityRects[i].top);
485 Stream_Read_UINT16(s, windowState->visibilityRects[i].right);
486 Stream_Read_UINT16(s,
487 windowState->visibilityRects[i].bottom);
492 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
494 if (!rail_read_unicode_string(s, &windowState->OverlayDescription))
498 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
503 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
505 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
508 Stream_Read_UINT8(s, windowState->TaskbarButton);
511 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
513 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
516 Stream_Read_UINT8(s, windowState->EnforceServerZOrder);
519 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
521 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
524 Stream_Read_UINT8(s, windowState->AppBarState);
527 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
529 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
532 Stream_Read_UINT8(s, windowState->AppBarEdge);
541 WINPR_UNUSED(orderInfo);
544 if (!window_icon->iconInfo)
547 return update_read_icon_info(s, window_icon->iconInfo);
553 WINPR_UNUSED(orderInfo);
554 return update_read_cached_icon_info(
555 s, &window_cached_icon->cachedIcon);
558static void update_read_window_delete_order(WINPR_ATTR_UNUSED
wStream* s,
564static BOOL window_order_supported(
const rdpSettings* settings, UINT32 fieldFlags)
566 const UINT32 mask = (WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE | WINDOW_ORDER_FIELD_RP_CONTENT |
567 WINDOW_ORDER_FIELD_ROOT_PARENT);
578 case WINDOW_LEVEL_SUPPORTED_EX:
581 case WINDOW_LEVEL_SUPPORTED:
582 return ((fieldFlags & mask) == 0) || dresult;
584 case WINDOW_LEVEL_NOT_SUPPORTED:
592#define DUMP_APPEND(buffer, size, ...) \
595 char* b = (buffer); \
597 size_t pos = strnlen(b, s); \
598 (void)_snprintf(&b[pos], s - pos, __VA_ARGS__); \
601static void dump_window_style(
char* buffer,
size_t bufferSize, UINT32 style)
603 DUMP_APPEND(buffer, bufferSize,
" style=<0x%" PRIx32
": ", style);
604 if (style & WS_BORDER)
605 DUMP_APPEND(buffer, bufferSize,
" border");
606 if (style & WS_CAPTION)
607 DUMP_APPEND(buffer, bufferSize,
" caption");
608 if (style & WS_CHILD)
609 DUMP_APPEND(buffer, bufferSize,
" child");
610 if (style & WS_CHILDWINDOW)
611 DUMP_APPEND(buffer, bufferSize,
" childwindow");
612 if (style & WS_CLIPCHILDREN)
613 DUMP_APPEND(buffer, bufferSize,
" clipchildren");
614 if (style & WS_CLIPSIBLINGS)
615 DUMP_APPEND(buffer, bufferSize,
" clipsiblings");
616 if (style & WS_DISABLED)
617 DUMP_APPEND(buffer, bufferSize,
" disabled");
618 if (style & WS_DLGFRAME)
619 DUMP_APPEND(buffer, bufferSize,
" dlgframe");
620 if (style & WS_GROUP)
621 DUMP_APPEND(buffer, bufferSize,
" group");
622 if (style & WS_HSCROLL)
623 DUMP_APPEND(buffer, bufferSize,
" hscroll");
624 if (style & WS_ICONIC)
625 DUMP_APPEND(buffer, bufferSize,
" iconic");
626 if (style & WS_MAXIMIZE)
627 DUMP_APPEND(buffer, bufferSize,
" maximize");
628 if (style & WS_MAXIMIZEBOX)
629 DUMP_APPEND(buffer, bufferSize,
" maximizebox");
630 if (style & WS_MINIMIZE)
631 DUMP_APPEND(buffer, bufferSize,
" minimize");
632 if (style & WS_MINIMIZEBOX)
633 DUMP_APPEND(buffer, bufferSize,
" minimizebox");
634 if (style & WS_POPUP)
635 DUMP_APPEND(buffer, bufferSize,
" popup");
636 if (style & WS_SIZEBOX)
637 DUMP_APPEND(buffer, bufferSize,
" sizebox");
638 if (style & WS_SYSMENU)
639 DUMP_APPEND(buffer, bufferSize,
" sysmenu");
640 if (style & WS_TABSTOP)
641 DUMP_APPEND(buffer, bufferSize,
" tabstop");
642 if (style & WS_THICKFRAME)
643 DUMP_APPEND(buffer, bufferSize,
" thickframe");
644 if (style & WS_VISIBLE)
645 DUMP_APPEND(buffer, bufferSize,
" visible");
646 if (style & WS_VSCROLL)
647 DUMP_APPEND(buffer, bufferSize,
" vscroll");
648 DUMP_APPEND(buffer, bufferSize,
">");
651static void dump_window_style_ex(
char* buffer,
size_t bufferSize, UINT32 extendedStyle)
653 DUMP_APPEND(buffer, bufferSize,
" styleEx=<0x%" PRIx32
": ", extendedStyle);
654 if (extendedStyle & WS_EX_ACCEPTFILES)
655 DUMP_APPEND(buffer, bufferSize,
" acceptfiles");
656 if (extendedStyle & WS_EX_APPWINDOW)
657 DUMP_APPEND(buffer, bufferSize,
" appwindow");
658 if (extendedStyle & WS_EX_CLIENTEDGE)
659 DUMP_APPEND(buffer, bufferSize,
" clientedge");
660 if (extendedStyle & WS_EX_COMPOSITED)
661 DUMP_APPEND(buffer, bufferSize,
" composited");
662 if (extendedStyle & WS_EX_CONTEXTHELP)
663 DUMP_APPEND(buffer, bufferSize,
" contexthelp");
664 if (extendedStyle & WS_EX_CONTROLPARENT)
665 DUMP_APPEND(buffer, bufferSize,
" controlparent");
666 if (extendedStyle & WS_EX_DLGMODALFRAME)
667 DUMP_APPEND(buffer, bufferSize,
" dlgmodalframe");
668 if (extendedStyle & WS_EX_LAYERED)
669 DUMP_APPEND(buffer, bufferSize,
" layered");
670 if (extendedStyle & WS_EX_LAYOUTRTL)
671 DUMP_APPEND(buffer, bufferSize,
" layoutrtl");
672 if (extendedStyle & WS_EX_LEFT)
673 DUMP_APPEND(buffer, bufferSize,
" left");
674 if (extendedStyle & WS_EX_LEFTSCROLLBAR)
675 DUMP_APPEND(buffer, bufferSize,
" leftscrollbar");
676 if (extendedStyle & WS_EX_LTRREADING)
677 DUMP_APPEND(buffer, bufferSize,
" ltrreading");
678 if (extendedStyle & WS_EX_MDICHILD)
679 DUMP_APPEND(buffer, bufferSize,
" mdichild");
680 if (extendedStyle & WS_EX_NOACTIVATE)
681 DUMP_APPEND(buffer, bufferSize,
" noactivate");
682 if (extendedStyle & WS_EX_NOINHERITLAYOUT)
683 DUMP_APPEND(buffer, bufferSize,
" noinheritlayout");
684#if defined(WS_EX_NOREDIRECTIONBITMAP)
685 if (extendedStyle & WS_EX_NOREDIRECTIONBITMAP)
686 DUMP_APPEND(buffer, bufferSize,
" noredirectionbitmap");
688 if (extendedStyle & WS_EX_RIGHT)
689 DUMP_APPEND(buffer, bufferSize,
" right");
690 if (extendedStyle & WS_EX_RIGHTSCROLLBAR)
691 DUMP_APPEND(buffer, bufferSize,
" rightscrollbar");
692 if (extendedStyle & WS_EX_RTLREADING)
693 DUMP_APPEND(buffer, bufferSize,
" rtlreading");
694 if (extendedStyle & WS_EX_STATICEDGE)
695 DUMP_APPEND(buffer, bufferSize,
" staticedge");
696 if (extendedStyle & WS_EX_TOOLWINDOW)
697 DUMP_APPEND(buffer, bufferSize,
" toolWindow");
698 if (extendedStyle & WS_EX_TOPMOST)
699 DUMP_APPEND(buffer, bufferSize,
" topMost");
700 if (extendedStyle & WS_EX_TRANSPARENT)
701 DUMP_APPEND(buffer, bufferSize,
" transparent");
702 if (extendedStyle & WS_EX_WINDOWEDGE)
703 DUMP_APPEND(buffer, bufferSize,
" windowedge");
704 DUMP_APPEND(buffer, bufferSize,
">");
707static void dump_window_state_order(wLog* log,
const char* msg,
const WINDOW_ORDER_INFO* order,
710 char buffer[3000] = WINPR_C_ARRAY_INIT;
711 const size_t bufferSize =
sizeof(buffer) - 1;
713 (void)_snprintf(buffer, bufferSize,
"%s windowId=%" PRIu32
"", msg, order->windowId);
715 if (order->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
716 DUMP_APPEND(buffer, bufferSize,
" owner=%" PRIu32
"", state->ownerWindowId);
717 if (order->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
719 dump_window_style(buffer, bufferSize, state->style);
720 dump_window_style_ex(buffer, bufferSize, state->extendedStyle);
723 if (order->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
725 const char* showStr =
nullptr;
726 switch (state->showState)
732 showStr =
"minimized";
735 showStr =
"maximized";
741 showStr =
"<unknown>";
744 DUMP_APPEND(buffer, bufferSize,
" show=%s", showStr);
747 if (order->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
749 char* title = rail_string_to_utf8_string(&state->titleInfo);
752 DUMP_APPEND(buffer, bufferSize,
" title=\"%s\"", title);
756 DUMP_APPEND(buffer, bufferSize,
" title=<decode failed>");
758 if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
759 DUMP_APPEND(buffer, bufferSize,
" clientOffset=(%" PRId32
",%" PRId32
")",
760 state->clientOffsetX, state->clientOffsetY);
761 if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
762 DUMP_APPEND(buffer, bufferSize,
" clientAreaWidth=%" PRIu32
" clientAreaHeight=%" PRIu32
"",
763 state->clientAreaWidth, state->clientAreaHeight);
764 if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
765 DUMP_APPEND(buffer, bufferSize,
766 " resizeMarginLeft=%" PRIu32
" resizeMarginRight=%" PRIu32
"",
767 state->resizeMarginLeft, state->resizeMarginRight);
768 if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
769 DUMP_APPEND(buffer, bufferSize,
770 " resizeMarginTop=%" PRIu32
" resizeMarginBottom=%" PRIu32
"",
771 state->resizeMarginTop, state->resizeMarginBottom);
772 if (order->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
773 DUMP_APPEND(buffer, bufferSize,
" rpContent=0x%" PRIx32
"", state->RPContent);
774 if (order->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
775 DUMP_APPEND(buffer, bufferSize,
" rootParent=0x%" PRIx32
"", state->rootParentHandle);
776 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
777 DUMP_APPEND(buffer, bufferSize,
" windowOffset=(%" PRId32
",%" PRId32
")",
778 state->windowOffsetX, state->windowOffsetY);
779 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
780 DUMP_APPEND(buffer, bufferSize,
" windowClientDelta=(%" PRId32
",%" PRId32
")",
781 state->windowClientDeltaX, state->windowClientDeltaY);
782 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
783 DUMP_APPEND(buffer, bufferSize,
" windowWidth=%" PRIu32
" windowHeight=%" PRIu32
"",
784 state->windowWidth, state->windowHeight);
786 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
788 DUMP_APPEND(buffer, bufferSize,
" windowRects=(");
789 for (UINT32 i = 0; i < state->numWindowRects; i++)
791 DUMP_APPEND(buffer, bufferSize,
"(%" PRIu16
",%" PRIu16
",%" PRIu16
",%" PRIu16
")",
792 state->windowRects[i].left, state->windowRects[i].top,
793 state->windowRects[i].right, state->windowRects[i].bottom);
795 DUMP_APPEND(buffer, bufferSize,
")");
798 if (order->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
799 DUMP_APPEND(buffer, bufferSize,
" visibleOffset=(%" PRId32
",%" PRId32
")",
800 state->visibleOffsetX, state->visibleOffsetY);
802 if (order->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
804 DUMP_APPEND(buffer, bufferSize,
" visibilityRects=(");
805 for (UINT32 i = 0; i < state->numVisibilityRects; i++)
807 DUMP_APPEND(buffer, bufferSize,
"(%" PRIu16
",%" PRIu16
",%" PRIu16
",%" PRIu16
")",
808 state->visibilityRects[i].left, state->visibilityRects[i].top,
809 state->visibilityRects[i].right, state->visibilityRects[i].bottom);
811 DUMP_APPEND(buffer, bufferSize,
")");
814 if (order->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
815 DUMP_APPEND(buffer, bufferSize,
" overlayDescr");
817 if (order->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
818 DUMP_APPEND(buffer, bufferSize,
" iconOverlayNull");
820 if (order->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
821 DUMP_APPEND(buffer, bufferSize,
" taskBarButton=0x%" PRIx8
"", state->TaskbarButton);
823 if (order->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
824 DUMP_APPEND(buffer, bufferSize,
" enforceServerZOrder=0x%" PRIx8
"",
825 state->EnforceServerZOrder);
826 if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
827 DUMP_APPEND(buffer, bufferSize,
" appBarState=0x%" PRIx8
"", state->AppBarState);
828 if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
830 const char* appBarEdgeStr =
nullptr;
831 switch (state->AppBarEdge)
834 appBarEdgeStr =
"left";
837 appBarEdgeStr =
"top";
840 appBarEdgeStr =
"right";
843 appBarEdgeStr =
"bottom";
846 appBarEdgeStr =
"<unknown>";
849 DUMP_APPEND(buffer, bufferSize,
" appBarEdge=%s", appBarEdgeStr);
852 WLog_Print(log, WLOG_DEBUG,
"%s", buffer);
855static BOOL update_recv_window_info_order(rdpUpdate* update,
wStream* s,
859 rdpContext* context = update->context;
860 rdpWindowUpdate* window = update->window;
865 WINPR_ASSERT(context);
866 WINPR_ASSERT(window);
867 WINPR_ASSERT(orderInfo);
869 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
872 Stream_Read_UINT32(s, orderInfo->windowId);
874 if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
877 result = update_read_window_icon_order(s, orderInfo, &window_icon);
881 WLog_Print(up->log, WLOG_DEBUG,
"WindowIcon windowId=0x%" PRIx32
"",
882 orderInfo->windowId);
883 IFCALLRET(window->WindowIcon, result, context, orderInfo, &window_icon);
886 update_free_window_icon_info(window_icon.iconInfo);
887 free(window_icon.iconInfo);
889 else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
892 result = update_read_window_cached_icon_order(s, orderInfo, &window_cached_icon);
896 WLog_Print(up->log, WLOG_DEBUG,
"WindowCachedIcon windowId=0x%" PRIx32
"",
897 orderInfo->windowId);
898 IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window_cached_icon);
901 else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
903 update_read_window_delete_order(s, orderInfo);
904 WLog_Print(up->log, WLOG_DEBUG,
"WindowDelete windowId=0x%" PRIx32
"", orderInfo->windowId);
905 IFCALLRET(window->WindowDelete, result, context, orderInfo);
910 result = update_read_window_state_order(s, orderInfo, &windowState);
914 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
916 dump_window_state_order(up->log,
"WindowCreate", orderInfo, &windowState);
917 IFCALLRET(window->WindowCreate, result, context, orderInfo, &windowState);
921 dump_window_state_order(up->log,
"WindowUpdate", orderInfo, &windowState);
922 IFCALLRET(window->WindowUpdate, result, context, orderInfo, &windowState);
925 update_free_window_state(&windowState);
934 WINPR_ASSERT(notify);
935 rail_unicode_string_free(¬ify->toolTip);
936 rail_unicode_string_free(¬ify->infoTip.text);
937 rail_unicode_string_free(¬ify->infoTip.title);
938 update_free_window_icon_info(¬ify->icon);
945 WINPR_ASSERT(orderInfo);
946 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
948 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
951 Stream_Read_UINT32(s, notify_icon_state->version);
954 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
956 if (!rail_read_unicode_string(s,
957 ¬ify_icon_state->toolTip))
961 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
963 if (!update_read_notify_icon_infotip(
964 s, ¬ify_icon_state->infoTip))
968 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
970 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
973 Stream_Read_UINT32(s, notify_icon_state->state);
976 if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
978 if (!update_read_icon_info(s, ¬ify_icon_state->icon))
982 if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
984 if (!update_read_cached_icon_info(
985 s, ¬ify_icon_state->cachedIcon))
993update_read_notification_icon_delete_order(WINPR_ATTR_UNUSED
wStream* s,
999static BOOL update_recv_notification_icon_info_order(rdpUpdate* update,
wStream* s,
1003 rdpContext* context = update->context;
1004 rdpWindowUpdate* window = update->window;
1008 WINPR_ASSERT(orderInfo);
1009 WINPR_ASSERT(context);
1010 WINPR_ASSERT(window);
1012 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1015 Stream_Read_UINT32(s, orderInfo->windowId);
1016 Stream_Read_UINT32(s, orderInfo->notifyIconId);
1018 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
1020 update_read_notification_icon_delete_order(s, orderInfo);
1021 WLog_Print(up->log, WLOG_DEBUG,
"NotifyIconDelete");
1022 IFCALLRET(window->NotifyIconDelete, result, context, orderInfo);
1027 result = update_read_notification_icon_state_order(s, orderInfo, ¬ify_icon_state);
1032 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
1034 WLog_Print(up->log, WLOG_DEBUG,
"NotifyIconCreate");
1035 IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, ¬ify_icon_state);
1039 WLog_Print(up->log, WLOG_DEBUG,
"NotifyIconUpdate");
1040 IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, ¬ify_icon_state);
1043 update_notify_icon_state_order_free(¬ify_icon_state);
1049static BOOL update_read_desktop_actively_monitored_order(
wStream* s,
1053 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1055 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1058 Stream_Read_UINT32(s, monitored_desktop->activeWindowId);
1061 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1063 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
1066 Stream_Read_UINT8(s, monitored_desktop->numWindowIds);
1068 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, monitored_desktop->numWindowIds, 4ull))
1070 monitored_desktop->numWindowIds = 0;
1074 if (monitored_desktop->numWindowIds > 0)
1076 const size_t size =
sizeof(UINT32) * monitored_desktop->numWindowIds;
1077 UINT32* newid = (UINT32*)realloc(monitored_desktop->windowIds, size);
1081 free(monitored_desktop->windowIds);
1082 monitored_desktop->windowIds =
nullptr;
1083 monitored_desktop->numWindowIds = 0;
1087 monitored_desktop->windowIds = newid;
1090 for (UINT32 i = 0; i < monitored_desktop->numWindowIds; i++)
1092 Stream_Read_UINT32(s, monitored_desktop->windowIds[i]);
1097 free(monitored_desktop->windowIds);
1098 monitored_desktop->windowIds =
nullptr;
1105static void update_read_desktop_non_monitored_order(WINPR_ATTR_UNUSED
wStream* s,
1111static void dump_monitored_desktop(wLog* log,
const char* msg,
const WINDOW_ORDER_INFO* orderInfo,
1114 char buffer[1000] = WINPR_C_ARRAY_INIT;
1115 const size_t bufferSize =
sizeof(buffer) - 1;
1117 DUMP_APPEND(buffer, bufferSize,
"%s", msg);
1119 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1120 DUMP_APPEND(buffer, bufferSize,
" activeWindowId=0x%" PRIx32
"", monitored->activeWindowId);
1122 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1124 DUMP_APPEND(buffer, bufferSize,
" windows=(");
1125 for (UINT32 i = 0; i < monitored->numWindowIds; i++)
1127 WINPR_ASSERT(monitored->windowIds);
1128 DUMP_APPEND(buffer, bufferSize,
"0x%" PRIx32
",", monitored->windowIds[i]);
1130 DUMP_APPEND(buffer, bufferSize,
")");
1132 WLog_Print(log, WLOG_DEBUG,
"%s", buffer);
1135static BOOL update_recv_desktop_info_order(rdpUpdate* update,
wStream* s,
1139 rdpContext* context = update->context;
1140 rdpWindowUpdate* window = update->window;
1144 WINPR_ASSERT(orderInfo);
1145 WINPR_ASSERT(context);
1146 WINPR_ASSERT(window);
1148 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE)
1150 update_read_desktop_non_monitored_order(s, orderInfo);
1151 WLog_Print(up->log, WLOG_DEBUG,
"NonMonitoredDesktop, windowId=0x%" PRIx32
"",
1152 orderInfo->windowId);
1153 IFCALLRET(window->NonMonitoredDesktop, result, context, orderInfo);
1158 result = update_read_desktop_actively_monitored_order(s, orderInfo, &monitored_desktop);
1162 dump_monitored_desktop(up->log,
"ActivelyMonitoredDesktop", orderInfo,
1163 &monitored_desktop);
1164 IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &monitored_desktop);
1167 free(monitored_desktop.windowIds);
1173void update_free_window_icon_info(
ICON_INFO* iconInfo)
1178 free(iconInfo->bitsColor);
1179 iconInfo->bitsColor =
nullptr;
1180 free(iconInfo->bitsMask);
1181 iconInfo->bitsMask =
nullptr;
1182 free(iconInfo->colorTable);
1183 iconInfo->colorTable =
nullptr;
1186BOOL update_recv_altsec_window_order(rdpUpdate* update,
wStream* s)
1189 size_t remaining = 0;
1190 UINT16 orderSize = 0;
1194 remaining = Stream_GetRemainingLength(s);
1196 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1199 Stream_Read_UINT16(s, orderSize);
1200 Stream_Read_UINT32(s, orderInfo.fieldFlags);
1202 if (remaining + 1 < orderSize)
1204 WLog_Print(up->log, WLOG_ERROR,
"Stream short orderSize");
1208 if (!window_order_supported(update->context->settings, orderInfo.fieldFlags))
1210 WLog_INFO(TAG,
"Window order %08" PRIx32
" not supported!", orderInfo.fieldFlags);
1214 if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
1215 rc = update_recv_window_info_order(update, s, &orderInfo);
1216 else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY)
1217 rc = update_recv_notification_icon_info_order(update, s, &orderInfo);
1218 else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP)
1219 rc = update_recv_desktop_info_order(update, s, &orderInfo);
1222 WLog_Print(up->log, WLOG_ERROR,
"windoworder flags %08" PRIx32
" failed",
1223 orderInfo.fieldFlags);
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.