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);
65 const size_t charlen = unicode_string->length /
sizeof(WCHAR);
66 if (_wcsnlen(unicode_string->string, charlen) != charlen)
68 WLog_ERR(TAG,
"Failed to read UNICODE_STRING, data contains \\0 characters!");
76 if (!s || !unicode_string)
77 return ERROR_INVALID_PARAMETER;
79 const size_t length = unicode_string->length;
80 WINPR_ASSERT((length %
sizeof(WCHAR)) == 0);
83 if (!Stream_EnsureRemainingCapacity(s, length))
85 WLog_ERR(TAG,
"Stream_EnsureRemainingCapacity failed!");
86 return CHANNEL_RC_NO_MEMORY;
89 Stream_Write(s, unicode_string->string, length);
97 if (!s || !unicode_string)
98 return ERROR_INVALID_PARAMETER;
100 if (!Stream_EnsureRemainingCapacity(s, 2 + unicode_string->length))
102 WLog_ERR(TAG,
"Stream_EnsureRemainingCapacity failed!");
103 return CHANNEL_RC_NO_MEMORY;
106 Stream_Write_UINT16(s, unicode_string->length);
107 return rail_write_unicode_string_value(s, unicode_string);
112 WINPR_ASSERT(unicode_string);
113 free(unicode_string->string);
114 unicode_string->string =
nullptr;
115 unicode_string->length = 0;
120 WINPR_ASSERT(unicode_string);
122 rail_unicode_string_free(unicode_string);
124 if (!
string || strlen(
string) < 1)
128 WCHAR* buffer = ConvertUtf8ToWCharAlloc(
string, &len);
130 const size_t wlen = len *
sizeof(WCHAR);
131 if (!buffer || (wlen > UINT16_MAX))
137 unicode_string->string = buffer;
138 unicode_string->length = WINPR_ASSERTING_INT_CAST(UINT16, len *
sizeof(WCHAR));
144 WINPR_ASSERT(unicode_string);
145 WINPR_ASSERT((unicode_string->length %
sizeof(WCHAR)) == 0);
146 WINPR_ASSERT(((unicode_string->length > 0) && (unicode_string->string)) ||
147 (unicode_string->length == 0));
150 size_t inLen = unicode_string->length /
sizeof(WCHAR);
151 return ConvertWCharNToUtf8Alloc(unicode_string->string, inLen, &outLen);
157 BYTE* newBitMask =
nullptr;
159 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
162 Stream_Read_UINT16(s, iconInfo->cacheEntry);
163 Stream_Read_UINT8(s, iconInfo->cacheId);
164 Stream_Read_UINT8(s, iconInfo->bpp);
166 if ((iconInfo->bpp < 1) || (iconInfo->bpp > 32))
168 WLog_ERR(TAG,
"invalid bpp value %" PRIu32
"", iconInfo->bpp);
172 Stream_Read_UINT16(s, iconInfo->width);
173 Stream_Read_UINT16(s, iconInfo->height);
176 switch (iconInfo->bpp)
181 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
184 Stream_Read_UINT16(s, iconInfo->cbColorTable);
188 iconInfo->cbColorTable = 0;
192 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
195 Stream_Read_UINT16(s, iconInfo->cbBitsMask);
196 Stream_Read_UINT16(s, iconInfo->cbBitsColor);
199 if (iconInfo->cbBitsMask > 0)
201 newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);
205 free(iconInfo->bitsMask);
206 iconInfo->bitsMask =
nullptr;
210 iconInfo->bitsMask = newBitMask;
211 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsMask))
213 Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);
217 free(iconInfo->bitsMask);
218 iconInfo->bitsMask =
nullptr;
219 iconInfo->cbBitsMask = 0;
223 if (iconInfo->cbColorTable > 0)
225 BYTE* new_tab =
nullptr;
226 new_tab = (BYTE*)realloc(iconInfo->colorTable, iconInfo->cbColorTable);
230 free(iconInfo->colorTable);
231 iconInfo->colorTable =
nullptr;
235 iconInfo->colorTable = new_tab;
239 free(iconInfo->colorTable);
240 iconInfo->colorTable =
nullptr;
243 if (iconInfo->colorTable)
245 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbColorTable))
247 Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable);
251 if (iconInfo->cbBitsColor > 0)
253 newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor);
257 free(iconInfo->bitsColor);
258 iconInfo->bitsColor =
nullptr;
262 iconInfo->bitsColor = newBitMask;
263 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsColor))
265 Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor);
269 free(iconInfo->bitsColor);
270 iconInfo->bitsColor =
nullptr;
271 iconInfo->cbBitsColor = 0;
278 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
281 Stream_Read_UINT16(s, cachedIconInfo->cacheEntry);
282 Stream_Read_UINT8(s, cachedIconInfo->cacheId);
288 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
291 Stream_Read_UINT32(s, notifyIconInfoTip->timeout);
292 Stream_Read_UINT32(s, notifyIconInfoTip->flags);
293 return rail_read_unicode_string(s, ¬ifyIconInfoTip->text) &&
294 rail_read_unicode_string(s, ¬ifyIconInfoTip->title);
303 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
305 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
308 Stream_Read_UINT32(s, windowState->ownerWindowId);
311 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
313 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
316 Stream_Read_UINT32(s, windowState->style);
317 Stream_Read_UINT32(s, windowState->extendedStyle);
320 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
322 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
325 Stream_Read_UINT8(s, windowState->showState);
328 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
330 if (!rail_read_unicode_string(s, &windowState->titleInfo))
334 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
336 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
339 Stream_Read_INT32(s, windowState->clientOffsetX);
340 Stream_Read_INT32(s, windowState->clientOffsetY);
343 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
345 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
348 Stream_Read_UINT32(s, windowState->clientAreaWidth);
349 Stream_Read_UINT32(s, windowState->clientAreaHeight);
352 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
354 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
357 Stream_Read_UINT32(s, windowState->resizeMarginLeft);
358 Stream_Read_UINT32(s, windowState->resizeMarginRight);
361 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
363 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
366 Stream_Read_UINT32(s, windowState->resizeMarginTop);
367 Stream_Read_UINT32(s, windowState->resizeMarginBottom);
370 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
372 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
375 Stream_Read_UINT8(s, windowState->RPContent);
378 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
380 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
383 Stream_Read_UINT32(s, windowState->rootParentHandle);
386 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
388 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
391 Stream_Read_INT32(s, windowState->windowOffsetX);
392 Stream_Read_INT32(s, windowState->windowOffsetY);
395 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
397 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
400 Stream_Read_INT32(s, windowState->windowClientDeltaX);
401 Stream_Read_INT32(s, windowState->windowClientDeltaY);
404 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
406 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
409 Stream_Read_UINT32(s, windowState->windowWidth);
410 Stream_Read_UINT32(s, windowState->windowHeight);
413 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
415 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
418 Stream_Read_UINT16(s, windowState->numWindowRects);
420 if (windowState->numWindowRects > 0)
422 size =
sizeof(
RECTANGLE_16) * windowState->numWindowRects;
423 newRect = (
RECTANGLE_16*)realloc(windowState->windowRects, size);
427 free(windowState->windowRects);
428 windowState->windowRects =
nullptr;
432 windowState->windowRects = newRect;
434 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numWindowRects, 8ull))
438 for (UINT32 i = 0; i < windowState->numWindowRects; i++)
440 Stream_Read_UINT16(s, windowState->windowRects[i].left);
441 Stream_Read_UINT16(s, windowState->windowRects[i].top);
442 Stream_Read_UINT16(s, windowState->windowRects[i].right);
443 Stream_Read_UINT16(s, windowState->windowRects[i].bottom);
448 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
450 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
453 Stream_Read_INT32(s, windowState->visibleOffsetX);
454 Stream_Read_INT32(s, windowState->visibleOffsetY);
457 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
459 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
462 Stream_Read_UINT16(s, windowState->numVisibilityRects);
464 if (windowState->numVisibilityRects != 0)
466 size =
sizeof(
RECTANGLE_16) * windowState->numVisibilityRects;
467 newRect = (
RECTANGLE_16*)realloc(windowState->visibilityRects, size);
471 free(windowState->visibilityRects);
472 windowState->visibilityRects =
nullptr;
476 windowState->visibilityRects = newRect;
478 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numVisibilityRects,
483 for (UINT32 i = 0; i < windowState->numVisibilityRects; i++)
485 Stream_Read_UINT16(s, windowState->visibilityRects[i].left);
486 Stream_Read_UINT16(s, windowState->visibilityRects[i].top);
487 Stream_Read_UINT16(s, windowState->visibilityRects[i].right);
488 Stream_Read_UINT16(s,
489 windowState->visibilityRects[i].bottom);
494 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
496 if (!rail_read_unicode_string(s, &windowState->OverlayDescription))
500 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
505 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
507 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
510 Stream_Read_UINT8(s, windowState->TaskbarButton);
513 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
515 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
518 Stream_Read_UINT8(s, windowState->EnforceServerZOrder);
521 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
523 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
526 Stream_Read_UINT8(s, windowState->AppBarState);
529 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
531 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
534 Stream_Read_UINT8(s, windowState->AppBarEdge);
543 WINPR_UNUSED(orderInfo);
546 if (!window_icon->iconInfo)
549 return update_read_icon_info(s, window_icon->iconInfo);
555 WINPR_UNUSED(orderInfo);
556 return update_read_cached_icon_info(
557 s, &window_cached_icon->cachedIcon);
560static void update_read_window_delete_order(WINPR_ATTR_UNUSED
wStream* s,
566static BOOL window_order_supported(
const rdpSettings* settings, UINT32 fieldFlags)
568 const UINT32 mask = (WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE | WINDOW_ORDER_FIELD_RP_CONTENT |
569 WINDOW_ORDER_FIELD_ROOT_PARENT);
580 case WINDOW_LEVEL_SUPPORTED_EX:
583 case WINDOW_LEVEL_SUPPORTED:
584 return ((fieldFlags & mask) == 0) || dresult;
586 case WINDOW_LEVEL_NOT_SUPPORTED:
594#define DUMP_APPEND(buffer, size, ...) \
597 char* b = (buffer); \
599 size_t pos = strnlen(b, s); \
600 (void)_snprintf(&b[pos], s - pos, __VA_ARGS__); \
603static void dump_window_style(
char* buffer,
size_t bufferSize, UINT32 style)
605 DUMP_APPEND(buffer, bufferSize,
" style=<0x%" PRIx32
": ", style);
606 if (style & WS_BORDER)
607 DUMP_APPEND(buffer, bufferSize,
" border");
608 if (style & WS_CAPTION)
609 DUMP_APPEND(buffer, bufferSize,
" caption");
610 if (style & WS_CHILD)
611 DUMP_APPEND(buffer, bufferSize,
" child");
612 if (style & WS_CHILDWINDOW)
613 DUMP_APPEND(buffer, bufferSize,
" childwindow");
614 if (style & WS_CLIPCHILDREN)
615 DUMP_APPEND(buffer, bufferSize,
" clipchildren");
616 if (style & WS_CLIPSIBLINGS)
617 DUMP_APPEND(buffer, bufferSize,
" clipsiblings");
618 if (style & WS_DISABLED)
619 DUMP_APPEND(buffer, bufferSize,
" disabled");
620 if (style & WS_DLGFRAME)
621 DUMP_APPEND(buffer, bufferSize,
" dlgframe");
622 if (style & WS_GROUP)
623 DUMP_APPEND(buffer, bufferSize,
" group");
624 if (style & WS_HSCROLL)
625 DUMP_APPEND(buffer, bufferSize,
" hscroll");
626 if (style & WS_ICONIC)
627 DUMP_APPEND(buffer, bufferSize,
" iconic");
628 if (style & WS_MAXIMIZE)
629 DUMP_APPEND(buffer, bufferSize,
" maximize");
630 if (style & WS_MAXIMIZEBOX)
631 DUMP_APPEND(buffer, bufferSize,
" maximizebox");
632 if (style & WS_MINIMIZE)
633 DUMP_APPEND(buffer, bufferSize,
" minimize");
634 if (style & WS_MINIMIZEBOX)
635 DUMP_APPEND(buffer, bufferSize,
" minimizebox");
636 if (style & WS_POPUP)
637 DUMP_APPEND(buffer, bufferSize,
" popup");
638 if (style & WS_SIZEBOX)
639 DUMP_APPEND(buffer, bufferSize,
" sizebox");
640 if (style & WS_SYSMENU)
641 DUMP_APPEND(buffer, bufferSize,
" sysmenu");
642 if (style & WS_TABSTOP)
643 DUMP_APPEND(buffer, bufferSize,
" tabstop");
644 if (style & WS_THICKFRAME)
645 DUMP_APPEND(buffer, bufferSize,
" thickframe");
646 if (style & WS_VISIBLE)
647 DUMP_APPEND(buffer, bufferSize,
" visible");
648 if (style & WS_VSCROLL)
649 DUMP_APPEND(buffer, bufferSize,
" vscroll");
650 DUMP_APPEND(buffer, bufferSize,
">");
653static void dump_window_style_ex(
char* buffer,
size_t bufferSize, UINT32 extendedStyle)
655 DUMP_APPEND(buffer, bufferSize,
" styleEx=<0x%" PRIx32
": ", extendedStyle);
656 if (extendedStyle & WS_EX_ACCEPTFILES)
657 DUMP_APPEND(buffer, bufferSize,
" acceptfiles");
658 if (extendedStyle & WS_EX_APPWINDOW)
659 DUMP_APPEND(buffer, bufferSize,
" appwindow");
660 if (extendedStyle & WS_EX_CLIENTEDGE)
661 DUMP_APPEND(buffer, bufferSize,
" clientedge");
662 if (extendedStyle & WS_EX_COMPOSITED)
663 DUMP_APPEND(buffer, bufferSize,
" composited");
664 if (extendedStyle & WS_EX_CONTEXTHELP)
665 DUMP_APPEND(buffer, bufferSize,
" contexthelp");
666 if (extendedStyle & WS_EX_CONTROLPARENT)
667 DUMP_APPEND(buffer, bufferSize,
" controlparent");
668 if (extendedStyle & WS_EX_DLGMODALFRAME)
669 DUMP_APPEND(buffer, bufferSize,
" dlgmodalframe");
670 if (extendedStyle & WS_EX_LAYERED)
671 DUMP_APPEND(buffer, bufferSize,
" layered");
672 if (extendedStyle & WS_EX_LAYOUTRTL)
673 DUMP_APPEND(buffer, bufferSize,
" layoutrtl");
674 if (extendedStyle & WS_EX_LEFT)
675 DUMP_APPEND(buffer, bufferSize,
" left");
676 if (extendedStyle & WS_EX_LEFTSCROLLBAR)
677 DUMP_APPEND(buffer, bufferSize,
" leftscrollbar");
678 if (extendedStyle & WS_EX_LTRREADING)
679 DUMP_APPEND(buffer, bufferSize,
" ltrreading");
680 if (extendedStyle & WS_EX_MDICHILD)
681 DUMP_APPEND(buffer, bufferSize,
" mdichild");
682 if (extendedStyle & WS_EX_NOACTIVATE)
683 DUMP_APPEND(buffer, bufferSize,
" noactivate");
684 if (extendedStyle & WS_EX_NOINHERITLAYOUT)
685 DUMP_APPEND(buffer, bufferSize,
" noinheritlayout");
686#if defined(WS_EX_NOREDIRECTIONBITMAP)
687 if (extendedStyle & WS_EX_NOREDIRECTIONBITMAP)
688 DUMP_APPEND(buffer, bufferSize,
" noredirectionbitmap");
690 if (extendedStyle & WS_EX_RIGHT)
691 DUMP_APPEND(buffer, bufferSize,
" right");
692 if (extendedStyle & WS_EX_RIGHTSCROLLBAR)
693 DUMP_APPEND(buffer, bufferSize,
" rightscrollbar");
694 if (extendedStyle & WS_EX_RTLREADING)
695 DUMP_APPEND(buffer, bufferSize,
" rtlreading");
696 if (extendedStyle & WS_EX_STATICEDGE)
697 DUMP_APPEND(buffer, bufferSize,
" staticedge");
698 if (extendedStyle & WS_EX_TOOLWINDOW)
699 DUMP_APPEND(buffer, bufferSize,
" toolWindow");
700 if (extendedStyle & WS_EX_TOPMOST)
701 DUMP_APPEND(buffer, bufferSize,
" topMost");
702 if (extendedStyle & WS_EX_TRANSPARENT)
703 DUMP_APPEND(buffer, bufferSize,
" transparent");
704 if (extendedStyle & WS_EX_WINDOWEDGE)
705 DUMP_APPEND(buffer, bufferSize,
" windowedge");
706 DUMP_APPEND(buffer, bufferSize,
">");
709static void dump_window_state_order(wLog* log,
const char* msg,
const WINDOW_ORDER_INFO* order,
712 char buffer[3000] = WINPR_C_ARRAY_INIT;
713 const size_t bufferSize =
sizeof(buffer) - 1;
715 (void)_snprintf(buffer, bufferSize,
"%s windowId=%" PRIu32
"", msg, order->windowId);
717 if (order->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
718 DUMP_APPEND(buffer, bufferSize,
" owner=%" PRIu32
"", state->ownerWindowId);
719 if (order->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
721 dump_window_style(buffer, bufferSize, state->style);
722 dump_window_style_ex(buffer, bufferSize, state->extendedStyle);
725 if (order->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
727 const char* showStr =
nullptr;
728 switch (state->showState)
734 showStr =
"minimized";
737 showStr =
"maximized";
743 showStr =
"<unknown>";
746 DUMP_APPEND(buffer, bufferSize,
" show=%s", showStr);
749 if (order->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
751 char* title = rail_string_to_utf8_string(&state->titleInfo);
754 DUMP_APPEND(buffer, bufferSize,
" title=\"%s\"", title);
758 DUMP_APPEND(buffer, bufferSize,
" title=<decode failed>");
760 if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
761 DUMP_APPEND(buffer, bufferSize,
" clientOffset=(%" PRId32
",%" PRId32
")",
762 state->clientOffsetX, state->clientOffsetY);
763 if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
764 DUMP_APPEND(buffer, bufferSize,
" clientAreaWidth=%" PRIu32
" clientAreaHeight=%" PRIu32
"",
765 state->clientAreaWidth, state->clientAreaHeight);
766 if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
767 DUMP_APPEND(buffer, bufferSize,
768 " resizeMarginLeft=%" PRIu32
" resizeMarginRight=%" PRIu32
"",
769 state->resizeMarginLeft, state->resizeMarginRight);
770 if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
771 DUMP_APPEND(buffer, bufferSize,
772 " resizeMarginTop=%" PRIu32
" resizeMarginBottom=%" PRIu32
"",
773 state->resizeMarginTop, state->resizeMarginBottom);
774 if (order->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
775 DUMP_APPEND(buffer, bufferSize,
" rpContent=0x%" PRIx32
"", state->RPContent);
776 if (order->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
777 DUMP_APPEND(buffer, bufferSize,
" rootParent=0x%" PRIx32
"", state->rootParentHandle);
778 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
779 DUMP_APPEND(buffer, bufferSize,
" windowOffset=(%" PRId32
",%" PRId32
")",
780 state->windowOffsetX, state->windowOffsetY);
781 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
782 DUMP_APPEND(buffer, bufferSize,
" windowClientDelta=(%" PRId32
",%" PRId32
")",
783 state->windowClientDeltaX, state->windowClientDeltaY);
784 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
785 DUMP_APPEND(buffer, bufferSize,
" windowWidth=%" PRIu32
" windowHeight=%" PRIu32
"",
786 state->windowWidth, state->windowHeight);
788 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
790 DUMP_APPEND(buffer, bufferSize,
" windowRects=(");
791 for (UINT32 i = 0; i < state->numWindowRects; i++)
793 DUMP_APPEND(buffer, bufferSize,
"(%" PRIu16
",%" PRIu16
",%" PRIu16
",%" PRIu16
")",
794 state->windowRects[i].left, state->windowRects[i].top,
795 state->windowRects[i].right, state->windowRects[i].bottom);
797 DUMP_APPEND(buffer, bufferSize,
")");
800 if (order->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
801 DUMP_APPEND(buffer, bufferSize,
" visibleOffset=(%" PRId32
",%" PRId32
")",
802 state->visibleOffsetX, state->visibleOffsetY);
804 if (order->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
806 DUMP_APPEND(buffer, bufferSize,
" visibilityRects=(");
807 for (UINT32 i = 0; i < state->numVisibilityRects; i++)
809 DUMP_APPEND(buffer, bufferSize,
"(%" PRIu16
",%" PRIu16
",%" PRIu16
",%" PRIu16
")",
810 state->visibilityRects[i].left, state->visibilityRects[i].top,
811 state->visibilityRects[i].right, state->visibilityRects[i].bottom);
813 DUMP_APPEND(buffer, bufferSize,
")");
816 if (order->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
817 DUMP_APPEND(buffer, bufferSize,
" overlayDescr");
819 if (order->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
820 DUMP_APPEND(buffer, bufferSize,
" iconOverlayNull");
822 if (order->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
823 DUMP_APPEND(buffer, bufferSize,
" taskBarButton=0x%" PRIx8
"", state->TaskbarButton);
825 if (order->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
826 DUMP_APPEND(buffer, bufferSize,
" enforceServerZOrder=0x%" PRIx8
"",
827 state->EnforceServerZOrder);
828 if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
829 DUMP_APPEND(buffer, bufferSize,
" appBarState=0x%" PRIx8
"", state->AppBarState);
830 if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
832 const char* appBarEdgeStr =
nullptr;
833 switch (state->AppBarEdge)
836 appBarEdgeStr =
"left";
839 appBarEdgeStr =
"top";
842 appBarEdgeStr =
"right";
845 appBarEdgeStr =
"bottom";
848 appBarEdgeStr =
"<unknown>";
851 DUMP_APPEND(buffer, bufferSize,
" appBarEdge=%s", appBarEdgeStr);
854 WLog_Print(log, WLOG_DEBUG,
"%s", buffer);
857static BOOL update_recv_window_info_order(rdpUpdate* update,
wStream* s,
861 rdpContext* context = update->context;
862 rdpWindowUpdate* window = update->window;
867 WINPR_ASSERT(context);
868 WINPR_ASSERT(window);
869 WINPR_ASSERT(orderInfo);
871 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
874 Stream_Read_UINT32(s, orderInfo->windowId);
876 if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
879 result = update_read_window_icon_order(s, orderInfo, &window_icon);
883 WLog_Print(up->log, WLOG_DEBUG,
"WindowIcon windowId=0x%" PRIx32
"",
884 orderInfo->windowId);
885 IFCALLRET(window->WindowIcon, result, context, orderInfo, &window_icon);
888 update_free_window_icon_info(window_icon.iconInfo);
889 free(window_icon.iconInfo);
891 else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
894 result = update_read_window_cached_icon_order(s, orderInfo, &window_cached_icon);
898 WLog_Print(up->log, WLOG_DEBUG,
"WindowCachedIcon windowId=0x%" PRIx32
"",
899 orderInfo->windowId);
900 IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window_cached_icon);
903 else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
905 update_read_window_delete_order(s, orderInfo);
906 WLog_Print(up->log, WLOG_DEBUG,
"WindowDelete windowId=0x%" PRIx32
"", orderInfo->windowId);
907 IFCALLRET(window->WindowDelete, result, context, orderInfo);
912 result = update_read_window_state_order(s, orderInfo, &windowState);
916 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
918 dump_window_state_order(up->log,
"WindowCreate", orderInfo, &windowState);
919 IFCALLRET(window->WindowCreate, result, context, orderInfo, &windowState);
923 dump_window_state_order(up->log,
"WindowUpdate", orderInfo, &windowState);
924 IFCALLRET(window->WindowUpdate, result, context, orderInfo, &windowState);
927 update_free_window_state(&windowState);
936 WINPR_ASSERT(notify);
937 rail_unicode_string_free(¬ify->toolTip);
938 rail_unicode_string_free(¬ify->infoTip.text);
939 rail_unicode_string_free(¬ify->infoTip.title);
940 update_free_window_icon_info(¬ify->icon);
947 WINPR_ASSERT(orderInfo);
948 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
950 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
953 Stream_Read_UINT32(s, notify_icon_state->version);
956 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
958 if (!rail_read_unicode_string(s,
959 ¬ify_icon_state->toolTip))
963 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
965 if (!update_read_notify_icon_infotip(
966 s, ¬ify_icon_state->infoTip))
970 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
972 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
975 Stream_Read_UINT32(s, notify_icon_state->state);
978 if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
980 if (!update_read_icon_info(s, ¬ify_icon_state->icon))
984 if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
986 if (!update_read_cached_icon_info(
987 s, ¬ify_icon_state->cachedIcon))
995update_read_notification_icon_delete_order(WINPR_ATTR_UNUSED
wStream* s,
1001static BOOL update_recv_notification_icon_info_order(rdpUpdate* update,
wStream* s,
1005 rdpContext* context = update->context;
1006 rdpWindowUpdate* window = update->window;
1010 WINPR_ASSERT(orderInfo);
1011 WINPR_ASSERT(context);
1012 WINPR_ASSERT(window);
1014 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
1017 Stream_Read_UINT32(s, orderInfo->windowId);
1018 Stream_Read_UINT32(s, orderInfo->notifyIconId);
1020 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
1022 update_read_notification_icon_delete_order(s, orderInfo);
1023 WLog_Print(up->log, WLOG_DEBUG,
"NotifyIconDelete");
1024 IFCALLRET(window->NotifyIconDelete, result, context, orderInfo);
1029 result = update_read_notification_icon_state_order(s, orderInfo, ¬ify_icon_state);
1034 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
1036 WLog_Print(up->log, WLOG_DEBUG,
"NotifyIconCreate");
1037 IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, ¬ify_icon_state);
1041 WLog_Print(up->log, WLOG_DEBUG,
"NotifyIconUpdate");
1042 IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, ¬ify_icon_state);
1045 update_notify_icon_state_order_free(¬ify_icon_state);
1051static BOOL update_read_desktop_actively_monitored_order(
wStream* s,
1055 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1057 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1060 Stream_Read_UINT32(s, monitored_desktop->activeWindowId);
1063 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1065 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
1068 Stream_Read_UINT8(s, monitored_desktop->numWindowIds);
1070 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, monitored_desktop->numWindowIds, 4ull))
1072 monitored_desktop->numWindowIds = 0;
1076 if (monitored_desktop->numWindowIds > 0)
1078 const size_t size =
sizeof(UINT32) * monitored_desktop->numWindowIds;
1079 UINT32* newid = (UINT32*)realloc(monitored_desktop->windowIds, size);
1083 free(monitored_desktop->windowIds);
1084 monitored_desktop->windowIds =
nullptr;
1085 monitored_desktop->numWindowIds = 0;
1089 monitored_desktop->windowIds = newid;
1092 for (UINT32 i = 0; i < monitored_desktop->numWindowIds; i++)
1094 Stream_Read_UINT32(s, monitored_desktop->windowIds[i]);
1099 free(monitored_desktop->windowIds);
1100 monitored_desktop->windowIds =
nullptr;
1107static void update_read_desktop_non_monitored_order(WINPR_ATTR_UNUSED
wStream* s,
1113static void dump_monitored_desktop(wLog* log,
const char* msg,
const WINDOW_ORDER_INFO* orderInfo,
1116 char buffer[1000] = WINPR_C_ARRAY_INIT;
1117 const size_t bufferSize =
sizeof(buffer) - 1;
1119 DUMP_APPEND(buffer, bufferSize,
"%s", msg);
1121 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1122 DUMP_APPEND(buffer, bufferSize,
" activeWindowId=0x%" PRIx32
"", monitored->activeWindowId);
1124 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1126 DUMP_APPEND(buffer, bufferSize,
" windows=(");
1127 for (UINT32 i = 0; i < monitored->numWindowIds; i++)
1129 WINPR_ASSERT(monitored->windowIds);
1130 DUMP_APPEND(buffer, bufferSize,
"0x%" PRIx32
",", monitored->windowIds[i]);
1132 DUMP_APPEND(buffer, bufferSize,
")");
1134 WLog_Print(log, WLOG_DEBUG,
"%s", buffer);
1137static BOOL update_recv_desktop_info_order(rdpUpdate* update,
wStream* s,
1141 rdpContext* context = update->context;
1142 rdpWindowUpdate* window = update->window;
1146 WINPR_ASSERT(orderInfo);
1147 WINPR_ASSERT(context);
1148 WINPR_ASSERT(window);
1150 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE)
1152 update_read_desktop_non_monitored_order(s, orderInfo);
1153 WLog_Print(up->log, WLOG_DEBUG,
"NonMonitoredDesktop, windowId=0x%" PRIx32
"",
1154 orderInfo->windowId);
1155 IFCALLRET(window->NonMonitoredDesktop, result, context, orderInfo);
1160 result = update_read_desktop_actively_monitored_order(s, orderInfo, &monitored_desktop);
1164 dump_monitored_desktop(up->log,
"ActivelyMonitoredDesktop", orderInfo,
1165 &monitored_desktop);
1166 IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &monitored_desktop);
1169 free(monitored_desktop.windowIds);
1175void update_free_window_icon_info(
ICON_INFO* iconInfo)
1180 free(iconInfo->bitsColor);
1181 iconInfo->bitsColor =
nullptr;
1182 free(iconInfo->bitsMask);
1183 iconInfo->bitsMask =
nullptr;
1184 free(iconInfo->colorTable);
1185 iconInfo->colorTable =
nullptr;
1188BOOL update_recv_altsec_window_order(rdpUpdate* update,
wStream* s)
1191 size_t remaining = 0;
1192 UINT16 orderSize = 0;
1196 remaining = Stream_GetRemainingLength(s);
1198 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1201 Stream_Read_UINT16(s, orderSize);
1202 Stream_Read_UINT32(s, orderInfo.fieldFlags);
1204 if (remaining + 1 < orderSize)
1206 WLog_Print(up->log, WLOG_ERROR,
"Stream short orderSize");
1210 if (!window_order_supported(update->context->settings, orderInfo.fieldFlags))
1212 WLog_INFO(TAG,
"Window order %08" PRIx32
" not supported!", orderInfo.fieldFlags);
1216 if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
1217 rc = update_recv_window_info_order(update, s, &orderInfo);
1218 else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY)
1219 rc = update_recv_notification_icon_info_order(update, s, &orderInfo);
1220 else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP)
1221 rc = update_recv_desktop_info_order(update, s, &orderInfo);
1224 WLog_Print(up->log, WLOG_ERROR,
"windoworder flags %08" PRIx32
" failed",
1225 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.