FreeRDP
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Modules Pages
window.c
1
21#include <freerdp/config.h>
22
23#include "settings.h"
24
25#include <winpr/crt.h>
26#include <winpr/assert.h>
27
28#include <freerdp/log.h>
29
30#include "window.h"
31
32#define TAG FREERDP_TAG("core.window")
33
34static void update_free_window_icon_info(ICON_INFO* iconInfo);
35
36BOOL rail_read_unicode_string(wStream* s, RAIL_UNICODE_STRING* unicode_string)
37{
38 UINT16 new_len = 0;
39 BYTE* new_str = NULL;
40
41 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
42 return FALSE;
43
44 Stream_Read_UINT16(s, new_len); /* cbString (2 bytes) */
45
46 if (!Stream_CheckAndLogRequiredLength(TAG, s, new_len))
47 return FALSE;
48
49 if (!new_len)
50 {
51 free(unicode_string->string);
52 unicode_string->string = NULL;
53 unicode_string->length = 0;
54 return TRUE;
55 }
56
57 new_str = (BYTE*)realloc(unicode_string->string, new_len);
58
59 if (!new_str)
60 {
61 free(unicode_string->string);
62 unicode_string->string = NULL;
63 return FALSE;
64 }
65
66 unicode_string->string = new_str;
67 unicode_string->length = new_len;
68 Stream_Read(s, unicode_string->string, unicode_string->length);
69 return TRUE;
70}
71
72BOOL utf8_string_to_rail_string(const char* string, RAIL_UNICODE_STRING* unicode_string)
73{
74 WCHAR* buffer = NULL;
75 size_t len = 0;
76 free(unicode_string->string);
77 unicode_string->string = NULL;
78 unicode_string->length = 0;
79
80 if (!string || strlen(string) < 1)
81 return TRUE;
82
83 buffer = ConvertUtf8ToWCharAlloc(string, &len);
84
85 if (!buffer || (len * sizeof(WCHAR) > UINT16_MAX))
86 {
87 free(buffer);
88 return FALSE;
89 }
90
91 unicode_string->string = (BYTE*)buffer;
92 unicode_string->length = (UINT16)len * sizeof(WCHAR);
93 return TRUE;
94}
95
96static char* rail_string_to_utf8_string(const RAIL_UNICODE_STRING* unicode_string)
97{
98 WINPR_ASSERT(unicode_string);
99
100 size_t outLen = 0;
101 size_t inLen = unicode_string->length / sizeof(WCHAR);
102 return ConvertWCharNToUtf8Alloc((const WCHAR*)unicode_string->string, inLen, &outLen);
103}
104
105/* See [MS-RDPERP] 2.2.1.2.3 Icon Info (TS_ICON_INFO) */
106static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
107{
108 BYTE* newBitMask = NULL;
109
110 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
111 return FALSE;
112
113 Stream_Read_UINT16(s, iconInfo->cacheEntry); /* cacheEntry (2 bytes) */
114 Stream_Read_UINT8(s, iconInfo->cacheId); /* cacheId (1 byte) */
115 Stream_Read_UINT8(s, iconInfo->bpp); /* bpp (1 byte) */
116
117 if ((iconInfo->bpp < 1) || (iconInfo->bpp > 32))
118 {
119 WLog_ERR(TAG, "invalid bpp value %" PRIu32 "", iconInfo->bpp);
120 return FALSE;
121 }
122
123 Stream_Read_UINT16(s, iconInfo->width); /* width (2 bytes) */
124 Stream_Read_UINT16(s, iconInfo->height); /* height (2 bytes) */
125
126 /* cbColorTable is only present when bpp is 1, 4 or 8 */
127 switch (iconInfo->bpp)
128 {
129 case 1:
130 case 4:
131 case 8:
132 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
133 return FALSE;
134
135 Stream_Read_UINT16(s, iconInfo->cbColorTable); /* cbColorTable (2 bytes) */
136 break;
137
138 default:
139 iconInfo->cbColorTable = 0;
140 break;
141 }
142
143 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
144 return FALSE;
145
146 Stream_Read_UINT16(s, iconInfo->cbBitsMask); /* cbBitsMask (2 bytes) */
147 Stream_Read_UINT16(s, iconInfo->cbBitsColor); /* cbBitsColor (2 bytes) */
148
149 /* bitsMask */
150 if (iconInfo->cbBitsMask > 0)
151 {
152 newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);
153
154 if (!newBitMask)
155 {
156 free(iconInfo->bitsMask);
157 iconInfo->bitsMask = NULL;
158 return FALSE;
159 }
160
161 iconInfo->bitsMask = newBitMask;
162 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsMask))
163 return FALSE;
164 Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);
165 }
166 else
167 {
168 free(iconInfo->bitsMask);
169 iconInfo->bitsMask = NULL;
170 iconInfo->cbBitsMask = 0;
171 }
172
173 /* colorTable */
174 if (iconInfo->cbColorTable > 0)
175 {
176 BYTE* new_tab = NULL;
177 new_tab = (BYTE*)realloc(iconInfo->colorTable, iconInfo->cbColorTable);
178
179 if (!new_tab)
180 {
181 free(iconInfo->colorTable);
182 iconInfo->colorTable = NULL;
183 return FALSE;
184 }
185
186 iconInfo->colorTable = new_tab;
187 }
188 else
189 {
190 free(iconInfo->colorTable);
191 iconInfo->colorTable = NULL;
192 }
193
194 if (iconInfo->colorTable)
195 {
196 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbColorTable))
197 return FALSE;
198 Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable);
199 }
200
201 /* bitsColor */
202 if (iconInfo->cbBitsColor > 0)
203 {
204 newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor);
205
206 if (!newBitMask)
207 {
208 free(iconInfo->bitsColor);
209 iconInfo->bitsColor = NULL;
210 return FALSE;
211 }
212
213 iconInfo->bitsColor = newBitMask;
214 if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsColor))
215 return FALSE;
216 Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor);
217 }
218 else
219 {
220 free(iconInfo->bitsColor);
221 iconInfo->bitsColor = NULL;
222 iconInfo->cbBitsColor = 0;
223 }
224 return TRUE;
225}
226
227static BOOL update_read_cached_icon_info(wStream* s, CACHED_ICON_INFO* cachedIconInfo)
228{
229 if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
230 return FALSE;
231
232 Stream_Read_UINT16(s, cachedIconInfo->cacheEntry); /* cacheEntry (2 bytes) */
233 Stream_Read_UINT8(s, cachedIconInfo->cacheId); /* cacheId (1 byte) */
234 return TRUE;
235}
236
237static BOOL update_read_notify_icon_infotip(wStream* s, NOTIFY_ICON_INFOTIP* notifyIconInfoTip)
238{
239 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
240 return FALSE;
241
242 Stream_Read_UINT32(s, notifyIconInfoTip->timeout); /* timeout (4 bytes) */
243 Stream_Read_UINT32(s, notifyIconInfoTip->flags); /* infoFlags (4 bytes) */
244 return rail_read_unicode_string(s, &notifyIconInfoTip->text) && /* infoTipText */
245 rail_read_unicode_string(s, &notifyIconInfoTip->title); /* title */
246}
247
248static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
249 WINDOW_STATE_ORDER* windowState)
250{
251 size_t size = 0;
252 RECTANGLE_16* newRect = NULL;
253
254 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
255 {
256 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
257 return FALSE;
258
259 Stream_Read_UINT32(s, windowState->ownerWindowId); /* ownerWindowId (4 bytes) */
260 }
261
262 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
263 {
264 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
265 return FALSE;
266
267 Stream_Read_UINT32(s, windowState->style); /* style (4 bytes) */
268 Stream_Read_UINT32(s, windowState->extendedStyle); /* extendedStyle (4 bytes) */
269 }
270
271 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
272 {
273 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
274 return FALSE;
275
276 Stream_Read_UINT8(s, windowState->showState); /* showState (1 byte) */
277 }
278
279 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
280 {
281 if (!rail_read_unicode_string(s, &windowState->titleInfo)) /* titleInfo */
282 return FALSE;
283 }
284
285 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
286 {
287 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
288 return FALSE;
289
290 Stream_Read_INT32(s, windowState->clientOffsetX); /* clientOffsetX (4 bytes) */
291 Stream_Read_INT32(s, windowState->clientOffsetY); /* clientOffsetY (4 bytes) */
292 }
293
294 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
295 {
296 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
297 return FALSE;
298
299 Stream_Read_UINT32(s, windowState->clientAreaWidth); /* clientAreaWidth (4 bytes) */
300 Stream_Read_UINT32(s, windowState->clientAreaHeight); /* clientAreaHeight (4 bytes) */
301 }
302
303 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
304 {
305 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
306 return FALSE;
307
308 Stream_Read_UINT32(s, windowState->resizeMarginLeft);
309 Stream_Read_UINT32(s, windowState->resizeMarginRight);
310 }
311
312 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
313 {
314 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
315 return FALSE;
316
317 Stream_Read_UINT32(s, windowState->resizeMarginTop);
318 Stream_Read_UINT32(s, windowState->resizeMarginBottom);
319 }
320
321 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
322 {
323 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
324 return FALSE;
325
326 Stream_Read_UINT8(s, windowState->RPContent); /* RPContent (1 byte) */
327 }
328
329 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
330 {
331 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
332 return FALSE;
333
334 Stream_Read_UINT32(s, windowState->rootParentHandle); /* rootParentHandle (4 bytes) */
335 }
336
337 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
338 {
339 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
340 return FALSE;
341
342 Stream_Read_INT32(s, windowState->windowOffsetX); /* windowOffsetX (4 bytes) */
343 Stream_Read_INT32(s, windowState->windowOffsetY); /* windowOffsetY (4 bytes) */
344 }
345
346 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
347 {
348 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
349 return FALSE;
350
351 Stream_Read_INT32(s, windowState->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */
352 Stream_Read_INT32(s, windowState->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */
353 }
354
355 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
356 {
357 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
358 return FALSE;
359
360 Stream_Read_UINT32(s, windowState->windowWidth); /* windowWidth (4 bytes) */
361 Stream_Read_UINT32(s, windowState->windowHeight); /* windowHeight (4 bytes) */
362 }
363
364 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
365 {
366 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
367 return FALSE;
368
369 Stream_Read_UINT16(s, windowState->numWindowRects); /* numWindowRects (2 bytes) */
370
371 if (windowState->numWindowRects > 0)
372 {
373 size = sizeof(RECTANGLE_16) * windowState->numWindowRects;
374 newRect = (RECTANGLE_16*)realloc(windowState->windowRects, size);
375
376 if (!newRect)
377 {
378 free(windowState->windowRects);
379 windowState->windowRects = NULL;
380 return FALSE;
381 }
382
383 windowState->windowRects = newRect;
384
385 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numWindowRects, 8ull))
386 return FALSE;
387
388 /* windowRects */
389 for (UINT32 i = 0; i < windowState->numWindowRects; i++)
390 {
391 Stream_Read_UINT16(s, windowState->windowRects[i].left); /* left (2 bytes) */
392 Stream_Read_UINT16(s, windowState->windowRects[i].top); /* top (2 bytes) */
393 Stream_Read_UINT16(s, windowState->windowRects[i].right); /* right (2 bytes) */
394 Stream_Read_UINT16(s, windowState->windowRects[i].bottom); /* bottom (2 bytes) */
395 }
396 }
397 }
398
399 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
400 {
401 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
402 return FALSE;
403
404 Stream_Read_INT32(s, windowState->visibleOffsetX); /* visibleOffsetX (4 bytes) */
405 Stream_Read_INT32(s, windowState->visibleOffsetY); /* visibleOffsetY (4 bytes) */
406 }
407
408 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
409 {
410 if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
411 return FALSE;
412
413 Stream_Read_UINT16(s, windowState->numVisibilityRects); /* numVisibilityRects (2 bytes) */
414
415 if (windowState->numVisibilityRects != 0)
416 {
417 size = sizeof(RECTANGLE_16) * windowState->numVisibilityRects;
418 newRect = (RECTANGLE_16*)realloc(windowState->visibilityRects, size);
419
420 if (!newRect)
421 {
422 free(windowState->visibilityRects);
423 windowState->visibilityRects = NULL;
424 return FALSE;
425 }
426
427 windowState->visibilityRects = newRect;
428
429 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numVisibilityRects,
430 8ull))
431 return FALSE;
432
433 /* visibilityRects */
434 for (UINT32 i = 0; i < windowState->numVisibilityRects; i++)
435 {
436 Stream_Read_UINT16(s, windowState->visibilityRects[i].left); /* left (2 bytes) */
437 Stream_Read_UINT16(s, windowState->visibilityRects[i].top); /* top (2 bytes) */
438 Stream_Read_UINT16(s, windowState->visibilityRects[i].right); /* right (2 bytes) */
439 Stream_Read_UINT16(s,
440 windowState->visibilityRects[i].bottom); /* bottom (2 bytes) */
441 }
442 }
443 }
444
445 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
446 {
447 if (!rail_read_unicode_string(s, &windowState->OverlayDescription))
448 return FALSE;
449 }
450
451 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
452 {
453 /* no data to be read here */
454 }
455
456 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
457 {
458 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
459 return FALSE;
460
461 Stream_Read_UINT8(s, windowState->TaskbarButton);
462 }
463
464 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
465 {
466 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
467 return FALSE;
468
469 Stream_Read_UINT8(s, windowState->EnforceServerZOrder);
470 }
471
472 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
473 {
474 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
475 return FALSE;
476
477 Stream_Read_UINT8(s, windowState->AppBarState);
478 }
479
480 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
481 {
482 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
483 return FALSE;
484
485 Stream_Read_UINT8(s, windowState->AppBarEdge);
486 }
487
488 return TRUE;
489}
490
491static BOOL update_read_window_icon_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
492 WINDOW_ICON_ORDER* window_icon)
493{
494 WINPR_UNUSED(orderInfo);
495 window_icon->iconInfo = (ICON_INFO*)calloc(1, sizeof(ICON_INFO));
496
497 if (!window_icon->iconInfo)
498 return FALSE;
499
500 return update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */
501}
502
503static BOOL update_read_window_cached_icon_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
504 WINDOW_CACHED_ICON_ORDER* window_cached_icon)
505{
506 WINPR_UNUSED(orderInfo);
507 return update_read_cached_icon_info(
508 s, &window_cached_icon->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */
509}
510
511static void update_read_window_delete_order(WINPR_ATTR_UNUSED wStream* s,
512 WINPR_ATTR_UNUSED WINDOW_ORDER_INFO* orderInfo)
513{
514 /* window deletion event */
515}
516
517static BOOL window_order_supported(const rdpSettings* settings, UINT32 fieldFlags)
518{
519 const UINT32 mask = (WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE | WINDOW_ORDER_FIELD_RP_CONTENT |
520 WINDOW_ORDER_FIELD_ROOT_PARENT);
521 BOOL dresult = 0;
522
523 if (!settings)
524 return FALSE;
525
526 /* See [MS-RDPERP] 2.2.1.1.2 Window List Capability Set */
527 dresult = settings->AllowUnanouncedOrdersFromServer;
528
529 switch (settings->RemoteWndSupportLevel)
530 {
531 case WINDOW_LEVEL_SUPPORTED_EX:
532 return TRUE;
533
534 case WINDOW_LEVEL_SUPPORTED:
535 return ((fieldFlags & mask) == 0) || dresult;
536
537 case WINDOW_LEVEL_NOT_SUPPORTED:
538 return dresult;
539
540 default:
541 return dresult;
542 }
543}
544
545#define DUMP_APPEND(buffer, size, ...) \
546 do \
547 { \
548 char* b = (buffer); \
549 size_t s = (size); \
550 size_t pos = strnlen(b, s); \
551 (void)_snprintf(&b[pos], s - pos, __VA_ARGS__); \
552 } while (0)
553
554static void dump_window_style(char* buffer, size_t bufferSize, UINT32 style)
555{
556 DUMP_APPEND(buffer, bufferSize, " style=<0x%" PRIx32 ": ", style);
557 if (style & WS_BORDER)
558 DUMP_APPEND(buffer, bufferSize, " border");
559 if (style & WS_CAPTION)
560 DUMP_APPEND(buffer, bufferSize, " caption");
561 if (style & WS_CHILD)
562 DUMP_APPEND(buffer, bufferSize, " child");
563 if (style & WS_CHILDWINDOW)
564 DUMP_APPEND(buffer, bufferSize, " childwindow");
565 if (style & WS_CLIPCHILDREN)
566 DUMP_APPEND(buffer, bufferSize, " clipchildren");
567 if (style & WS_CLIPSIBLINGS)
568 DUMP_APPEND(buffer, bufferSize, " clipsiblings");
569 if (style & WS_DISABLED)
570 DUMP_APPEND(buffer, bufferSize, " disabled");
571 if (style & WS_DLGFRAME)
572 DUMP_APPEND(buffer, bufferSize, " dlgframe");
573 if (style & WS_GROUP)
574 DUMP_APPEND(buffer, bufferSize, " group");
575 if (style & WS_HSCROLL)
576 DUMP_APPEND(buffer, bufferSize, " hscroll");
577 if (style & WS_ICONIC)
578 DUMP_APPEND(buffer, bufferSize, " iconic");
579 if (style & WS_MAXIMIZE)
580 DUMP_APPEND(buffer, bufferSize, " maximize");
581 if (style & WS_MAXIMIZEBOX)
582 DUMP_APPEND(buffer, bufferSize, " maximizebox");
583 if (style & WS_MINIMIZE)
584 DUMP_APPEND(buffer, bufferSize, " minimize");
585 if (style & WS_MINIMIZEBOX)
586 DUMP_APPEND(buffer, bufferSize, " minimizebox");
587 if (style & WS_POPUP)
588 DUMP_APPEND(buffer, bufferSize, " popup");
589 if (style & WS_SIZEBOX)
590 DUMP_APPEND(buffer, bufferSize, " sizebox");
591 if (style & WS_SYSMENU)
592 DUMP_APPEND(buffer, bufferSize, " sysmenu");
593 if (style & WS_TABSTOP)
594 DUMP_APPEND(buffer, bufferSize, " tabstop");
595 if (style & WS_THICKFRAME)
596 DUMP_APPEND(buffer, bufferSize, " thickframe");
597 if (style & WS_VISIBLE)
598 DUMP_APPEND(buffer, bufferSize, " visible");
599 if (style & WS_VSCROLL)
600 DUMP_APPEND(buffer, bufferSize, " vscroll");
601 DUMP_APPEND(buffer, bufferSize, ">");
602}
603
604static void dump_window_style_ex(char* buffer, size_t bufferSize, UINT32 extendedStyle)
605{
606 DUMP_APPEND(buffer, bufferSize, " styleEx=<0x%" PRIx32 ": ", extendedStyle);
607 if (extendedStyle & WS_EX_ACCEPTFILES)
608 DUMP_APPEND(buffer, bufferSize, " acceptfiles");
609 if (extendedStyle & WS_EX_APPWINDOW)
610 DUMP_APPEND(buffer, bufferSize, " appwindow");
611 if (extendedStyle & WS_EX_CLIENTEDGE)
612 DUMP_APPEND(buffer, bufferSize, " clientedge");
613 if (extendedStyle & WS_EX_COMPOSITED)
614 DUMP_APPEND(buffer, bufferSize, " composited");
615 if (extendedStyle & WS_EX_CONTEXTHELP)
616 DUMP_APPEND(buffer, bufferSize, " contexthelp");
617 if (extendedStyle & WS_EX_CONTROLPARENT)
618 DUMP_APPEND(buffer, bufferSize, " controlparent");
619 if (extendedStyle & WS_EX_DLGMODALFRAME)
620 DUMP_APPEND(buffer, bufferSize, " dlgmodalframe");
621 if (extendedStyle & WS_EX_LAYERED)
622 DUMP_APPEND(buffer, bufferSize, " layered");
623 if (extendedStyle & WS_EX_LAYOUTRTL)
624 DUMP_APPEND(buffer, bufferSize, " layoutrtl");
625 if (extendedStyle & WS_EX_LEFT)
626 DUMP_APPEND(buffer, bufferSize, " left");
627 if (extendedStyle & WS_EX_LEFTSCROLLBAR)
628 DUMP_APPEND(buffer, bufferSize, " leftscrollbar");
629 if (extendedStyle & WS_EX_LTRREADING)
630 DUMP_APPEND(buffer, bufferSize, " ltrreading");
631 if (extendedStyle & WS_EX_MDICHILD)
632 DUMP_APPEND(buffer, bufferSize, " mdichild");
633 if (extendedStyle & WS_EX_NOACTIVATE)
634 DUMP_APPEND(buffer, bufferSize, " noactivate");
635 if (extendedStyle & WS_EX_NOINHERITLAYOUT)
636 DUMP_APPEND(buffer, bufferSize, " noinheritlayout");
637#if defined(WS_EX_NOREDIRECTIONBITMAP)
638 if (extendedStyle & WS_EX_NOREDIRECTIONBITMAP)
639 DUMP_APPEND(buffer, bufferSize, " noredirectionbitmap");
640#endif
641 if (extendedStyle & WS_EX_RIGHT)
642 DUMP_APPEND(buffer, bufferSize, " right");
643 if (extendedStyle & WS_EX_RIGHTSCROLLBAR)
644 DUMP_APPEND(buffer, bufferSize, " rightscrollbar");
645 if (extendedStyle & WS_EX_RTLREADING)
646 DUMP_APPEND(buffer, bufferSize, " rtlreading");
647 if (extendedStyle & WS_EX_STATICEDGE)
648 DUMP_APPEND(buffer, bufferSize, " staticedge");
649 if (extendedStyle & WS_EX_TOOLWINDOW)
650 DUMP_APPEND(buffer, bufferSize, " toolWindow");
651 if (extendedStyle & WS_EX_TOPMOST)
652 DUMP_APPEND(buffer, bufferSize, " topMost");
653 if (extendedStyle & WS_EX_TRANSPARENT)
654 DUMP_APPEND(buffer, bufferSize, " transparent");
655 if (extendedStyle & WS_EX_WINDOWEDGE)
656 DUMP_APPEND(buffer, bufferSize, " windowedge");
657 DUMP_APPEND(buffer, bufferSize, ">");
658}
659
660static void dump_window_state_order(wLog* log, const char* msg, const WINDOW_ORDER_INFO* order,
661 const WINDOW_STATE_ORDER* state)
662{
663 char buffer[3000] = { 0 };
664 const size_t bufferSize = sizeof(buffer) - 1;
665
666 (void)_snprintf(buffer, bufferSize, "%s windowId=%" PRIu32 "", msg, order->windowId);
667
668 if (order->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
669 DUMP_APPEND(buffer, bufferSize, " owner=%" PRIu32 "", state->ownerWindowId);
670 if (order->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
671 {
672 dump_window_style(buffer, bufferSize, state->style);
673 dump_window_style_ex(buffer, bufferSize, state->extendedStyle);
674 }
675
676 if (order->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
677 {
678 const char* showStr = NULL;
679 switch (state->showState)
680 {
681 case 0:
682 showStr = "hidden";
683 break;
684 case 2:
685 showStr = "minimized";
686 break;
687 case 3:
688 showStr = "maximized";
689 break;
690 case 5:
691 showStr = "show";
692 break;
693 default:
694 showStr = "<unknown>";
695 break;
696 }
697 DUMP_APPEND(buffer, bufferSize, " show=%s", showStr);
698 }
699
700 if (order->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
701 {
702 char* title = rail_string_to_utf8_string(&state->titleInfo);
703 if (title)
704 {
705 DUMP_APPEND(buffer, bufferSize, " title=\"%s\"", title);
706 free(title);
707 }
708 else
709 DUMP_APPEND(buffer, bufferSize, " title=<decode failed>");
710 }
711 if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
712 DUMP_APPEND(buffer, bufferSize, " clientOffset=(%" PRId32 ",%" PRId32 ")",
713 state->clientOffsetX, state->clientOffsetY);
714 if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
715 DUMP_APPEND(buffer, bufferSize, " clientAreaWidth=%" PRIu32 " clientAreaHeight=%" PRIu32 "",
716 state->clientAreaWidth, state->clientAreaHeight);
717 if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
718 DUMP_APPEND(buffer, bufferSize,
719 " resizeMarginLeft=%" PRIu32 " resizeMarginRight=%" PRIu32 "",
720 state->resizeMarginLeft, state->resizeMarginRight);
721 if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
722 DUMP_APPEND(buffer, bufferSize,
723 " resizeMarginTop=%" PRIu32 " resizeMarginBottom=%" PRIu32 "",
724 state->resizeMarginTop, state->resizeMarginBottom);
725 if (order->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
726 DUMP_APPEND(buffer, bufferSize, " rpContent=0x%" PRIx32 "", state->RPContent);
727 if (order->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
728 DUMP_APPEND(buffer, bufferSize, " rootParent=0x%" PRIx32 "", state->rootParentHandle);
729 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
730 DUMP_APPEND(buffer, bufferSize, " windowOffset=(%" PRId32 ",%" PRId32 ")",
731 state->windowOffsetX, state->windowOffsetY);
732 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
733 DUMP_APPEND(buffer, bufferSize, " windowClientDelta=(%" PRId32 ",%" PRId32 ")",
734 state->windowClientDeltaX, state->windowClientDeltaY);
735 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
736 DUMP_APPEND(buffer, bufferSize, " windowWidth=%" PRIu32 " windowHeight=%" PRIu32 "",
737 state->windowWidth, state->windowHeight);
738
739 if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
740 {
741 DUMP_APPEND(buffer, bufferSize, " windowRects=(");
742 for (UINT32 i = 0; i < state->numWindowRects; i++)
743 {
744 DUMP_APPEND(buffer, bufferSize, "(%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ")",
745 state->windowRects[i].left, state->windowRects[i].top,
746 state->windowRects[i].right, state->windowRects[i].bottom);
747 }
748 DUMP_APPEND(buffer, bufferSize, ")");
749 }
750
751 if (order->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
752 DUMP_APPEND(buffer, bufferSize, " visibleOffset=(%" PRId32 ",%" PRId32 ")",
753 state->visibleOffsetX, state->visibleOffsetY);
754
755 if (order->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
756 {
757 DUMP_APPEND(buffer, bufferSize, " visibilityRects=(");
758 for (UINT32 i = 0; i < state->numVisibilityRects; i++)
759 {
760 DUMP_APPEND(buffer, bufferSize, "(%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ")",
761 state->visibilityRects[i].left, state->visibilityRects[i].top,
762 state->visibilityRects[i].right, state->visibilityRects[i].bottom);
763 }
764 DUMP_APPEND(buffer, bufferSize, ")");
765 }
766
767 if (order->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
768 DUMP_APPEND(buffer, bufferSize, " overlayDescr");
769
770 if (order->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
771 DUMP_APPEND(buffer, bufferSize, " iconOverlayNull");
772
773 if (order->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
774 DUMP_APPEND(buffer, bufferSize, " taskBarButton=0x%" PRIx8 "", state->TaskbarButton);
775
776 if (order->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
777 DUMP_APPEND(buffer, bufferSize, " enforceServerZOrder=0x%" PRIx8 "",
778 state->EnforceServerZOrder);
779 if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
780 DUMP_APPEND(buffer, bufferSize, " appBarState=0x%" PRIx8 "", state->AppBarState);
781 if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
782 {
783 const char* appBarEdgeStr = NULL;
784 switch (state->AppBarEdge)
785 {
786 case 0:
787 appBarEdgeStr = "left";
788 break;
789 case 1:
790 appBarEdgeStr = "top";
791 break;
792 case 2:
793 appBarEdgeStr = "right";
794 break;
795 case 3:
796 appBarEdgeStr = "bottom";
797 break;
798 default:
799 appBarEdgeStr = "<unknown>";
800 break;
801 }
802 DUMP_APPEND(buffer, bufferSize, " appBarEdge=%s", appBarEdgeStr);
803 }
804
805 WLog_Print(log, WLOG_DEBUG, buffer);
806}
807
808static BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s,
809 WINDOW_ORDER_INFO* orderInfo)
810{
811 rdp_update_internal* up = update_cast(update);
812 rdpContext* context = update->context;
813 rdpWindowUpdate* window = update->window;
814
815 BOOL result = TRUE;
816
817 WINPR_ASSERT(s);
818 WINPR_ASSERT(context);
819 WINPR_ASSERT(window);
820 WINPR_ASSERT(orderInfo);
821
822 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
823 return FALSE;
824
825 Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */
826
827 if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
828 {
829 WINDOW_ICON_ORDER window_icon = { 0 };
830 result = update_read_window_icon_order(s, orderInfo, &window_icon);
831
832 if (result)
833 {
834 WLog_Print(up->log, WLOG_DEBUG, "WindowIcon windowId=0x%" PRIx32 "",
835 orderInfo->windowId);
836 IFCALLRET(window->WindowIcon, result, context, orderInfo, &window_icon);
837 }
838
839 update_free_window_icon_info(window_icon.iconInfo);
840 free(window_icon.iconInfo);
841 }
842 else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
843 {
844 WINDOW_CACHED_ICON_ORDER window_cached_icon = { 0 };
845 result = update_read_window_cached_icon_order(s, orderInfo, &window_cached_icon);
846
847 if (result)
848 {
849 WLog_Print(up->log, WLOG_DEBUG, "WindowCachedIcon windowId=0x%" PRIx32 "",
850 orderInfo->windowId);
851 IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window_cached_icon);
852 }
853 }
854 else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
855 {
856 update_read_window_delete_order(s, orderInfo);
857 WLog_Print(up->log, WLOG_DEBUG, "WindowDelete windowId=0x%" PRIx32 "", orderInfo->windowId);
858 IFCALLRET(window->WindowDelete, result, context, orderInfo);
859 }
860 else
861 {
862 WINDOW_STATE_ORDER windowState = { 0 };
863 result = update_read_window_state_order(s, orderInfo, &windowState);
864
865 if (result)
866 {
867 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
868 {
869 dump_window_state_order(up->log, "WindowCreate", orderInfo, &windowState);
870 IFCALLRET(window->WindowCreate, result, context, orderInfo, &windowState);
871 }
872 else
873 {
874 dump_window_state_order(up->log, "WindowUpdate", orderInfo, &windowState);
875 IFCALLRET(window->WindowUpdate, result, context, orderInfo, &windowState);
876 }
877
878 update_free_window_state(&windowState);
879 }
880 }
881
882 return result;
883}
884
885static void update_notify_icon_state_order_free(NOTIFY_ICON_STATE_ORDER* notify)
886{
887 free(notify->toolTip.string);
888 free(notify->infoTip.text.string);
889 free(notify->infoTip.title.string);
890 update_free_window_icon_info(&notify->icon);
891 memset(notify, 0, sizeof(NOTIFY_ICON_STATE_ORDER));
892}
893
894static BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
895 NOTIFY_ICON_STATE_ORDER* notify_icon_state)
896{
897 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
898 {
899 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
900 return FALSE;
901
902 Stream_Read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */
903 }
904
905 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
906 {
907 if (!rail_read_unicode_string(s,
908 &notify_icon_state->toolTip)) /* toolTip (UNICODE_STRING) */
909 return FALSE;
910 }
911
912 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
913 {
914 if (!update_read_notify_icon_infotip(
915 s, &notify_icon_state->infoTip)) /* infoTip (NOTIFY_ICON_INFOTIP) */
916 return FALSE;
917 }
918
919 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
920 {
921 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
922 return FALSE;
923
924 Stream_Read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */
925 }
926
927 if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
928 {
929 if (!update_read_icon_info(s, &notify_icon_state->icon)) /* icon (ICON_INFO) */
930 return FALSE;
931 }
932
933 if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
934 {
935 if (!update_read_cached_icon_info(
936 s, &notify_icon_state->cachedIcon)) /* cachedIcon (CACHED_ICON_INFO) */
937 return FALSE;
938 }
939
940 return TRUE;
941}
942
943static void
944update_read_notification_icon_delete_order(WINPR_ATTR_UNUSED wStream* s,
945 WINPR_ATTR_UNUSED WINDOW_ORDER_INFO* orderInfo)
946{
947 /* notification icon deletion event */
948}
949
950static BOOL update_recv_notification_icon_info_order(rdpUpdate* update, wStream* s,
951 WINDOW_ORDER_INFO* orderInfo)
952{
953 rdp_update_internal* up = update_cast(update);
954 rdpContext* context = update->context;
955 rdpWindowUpdate* window = update->window;
956 BOOL result = TRUE;
957
958 WINPR_ASSERT(s);
959 WINPR_ASSERT(orderInfo);
960 WINPR_ASSERT(context);
961 WINPR_ASSERT(window);
962
963 if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
964 return FALSE;
965
966 Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */
967 Stream_Read_UINT32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */
968
969 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
970 {
971 update_read_notification_icon_delete_order(s, orderInfo);
972 WLog_Print(up->log, WLOG_DEBUG, "NotifyIconDelete");
973 IFCALLRET(window->NotifyIconDelete, result, context, orderInfo);
974 }
975 else
976 {
977 NOTIFY_ICON_STATE_ORDER notify_icon_state = { 0 };
978 result = update_read_notification_icon_state_order(s, orderInfo, &notify_icon_state);
979
980 if (!result)
981 goto fail;
982
983 if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
984 {
985 WLog_Print(up->log, WLOG_DEBUG, "NotifyIconCreate");
986 IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, &notify_icon_state);
987 }
988 else
989 {
990 WLog_Print(up->log, WLOG_DEBUG, "NotifyIconUpdate");
991 IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, &notify_icon_state);
992 }
993 fail:
994 update_notify_icon_state_order_free(&notify_icon_state);
995 }
996
997 return result;
998}
999
1000static BOOL update_read_desktop_actively_monitored_order(wStream* s,
1001 const WINDOW_ORDER_INFO* orderInfo,
1002 MONITORED_DESKTOP_ORDER* monitored_desktop)
1003{
1004 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1005 {
1006 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1007 return FALSE;
1008
1009 Stream_Read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */
1010 }
1011
1012 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1013 {
1014 if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
1015 return FALSE;
1016
1017 Stream_Read_UINT8(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */
1018
1019 if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, monitored_desktop->numWindowIds, 4ull))
1020 {
1021 monitored_desktop->numWindowIds = 0;
1022 return FALSE;
1023 }
1024
1025 if (monitored_desktop->numWindowIds > 0)
1026 {
1027 const size_t size = sizeof(UINT32) * monitored_desktop->numWindowIds;
1028 UINT32* newid = (UINT32*)realloc(monitored_desktop->windowIds, size);
1029
1030 if (!newid)
1031 {
1032 free(monitored_desktop->windowIds);
1033 monitored_desktop->windowIds = NULL;
1034 monitored_desktop->numWindowIds = 0;
1035 return FALSE;
1036 }
1037
1038 monitored_desktop->windowIds = newid;
1039
1040 /* windowIds */
1041 for (UINT32 i = 0; i < monitored_desktop->numWindowIds; i++)
1042 {
1043 Stream_Read_UINT32(s, monitored_desktop->windowIds[i]);
1044 }
1045 }
1046 else
1047 {
1048 free(monitored_desktop->windowIds);
1049 monitored_desktop->windowIds = NULL;
1050 }
1051 }
1052
1053 return TRUE;
1054}
1055
1056static void update_read_desktop_non_monitored_order(WINPR_ATTR_UNUSED wStream* s,
1057 WINPR_ATTR_UNUSED WINDOW_ORDER_INFO* orderInfo)
1058{
1059 /* non-monitored desktop notification event */
1060}
1061
1062static void dump_monitored_desktop(wLog* log, const char* msg, const WINDOW_ORDER_INFO* orderInfo,
1063 const MONITORED_DESKTOP_ORDER* monitored)
1064{
1065 char buffer[1000] = { 0 };
1066 const size_t bufferSize = sizeof(buffer) - 1;
1067
1068 DUMP_APPEND(buffer, bufferSize, "%s", msg);
1069
1070 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1071 DUMP_APPEND(buffer, bufferSize, " activeWindowId=0x%" PRIx32 "", monitored->activeWindowId);
1072
1073 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1074 {
1075 DUMP_APPEND(buffer, bufferSize, " windows=(");
1076 for (UINT32 i = 0; i < monitored->numWindowIds; i++)
1077 {
1078 WINPR_ASSERT(monitored->windowIds);
1079 DUMP_APPEND(buffer, bufferSize, "0x%" PRIx32 ",", monitored->windowIds[i]);
1080 }
1081 DUMP_APPEND(buffer, bufferSize, ")");
1082 }
1083 WLog_Print(log, WLOG_DEBUG, buffer);
1084}
1085
1086static BOOL update_recv_desktop_info_order(rdpUpdate* update, wStream* s,
1087 WINDOW_ORDER_INFO* orderInfo)
1088{
1089 rdp_update_internal* up = update_cast(update);
1090 rdpContext* context = update->context;
1091 rdpWindowUpdate* window = update->window;
1092 BOOL result = TRUE;
1093
1094 WINPR_ASSERT(s);
1095 WINPR_ASSERT(orderInfo);
1096 WINPR_ASSERT(context);
1097 WINPR_ASSERT(window);
1098
1099 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE)
1100 {
1101 update_read_desktop_non_monitored_order(s, orderInfo);
1102 WLog_Print(up->log, WLOG_DEBUG, "NonMonitoredDesktop, windowId=0x%" PRIx32 "",
1103 orderInfo->windowId);
1104 IFCALLRET(window->NonMonitoredDesktop, result, context, orderInfo);
1105 }
1106 else
1107 {
1108 MONITORED_DESKTOP_ORDER monitored_desktop = { 0 };
1109 result = update_read_desktop_actively_monitored_order(s, orderInfo, &monitored_desktop);
1110
1111 if (result)
1112 {
1113 dump_monitored_desktop(up->log, "ActivelyMonitoredDesktop", orderInfo,
1114 &monitored_desktop);
1115 IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &monitored_desktop);
1116 }
1117
1118 free(monitored_desktop.windowIds);
1119 }
1120
1121 return result;
1122}
1123
1124void update_free_window_icon_info(ICON_INFO* iconInfo)
1125{
1126 if (!iconInfo)
1127 return;
1128
1129 free(iconInfo->bitsColor);
1130 iconInfo->bitsColor = NULL;
1131 free(iconInfo->bitsMask);
1132 iconInfo->bitsMask = NULL;
1133 free(iconInfo->colorTable);
1134 iconInfo->colorTable = NULL;
1135}
1136
1137BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s)
1138{
1139 BOOL rc = TRUE;
1140 size_t remaining = 0;
1141 UINT16 orderSize = 0;
1142 WINDOW_ORDER_INFO orderInfo = { 0 };
1143 rdp_update_internal* up = update_cast(update);
1144
1145 remaining = Stream_GetRemainingLength(s);
1146
1147 if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1148 return FALSE;
1149
1150 Stream_Read_UINT16(s, orderSize); /* orderSize (2 bytes) */
1151 Stream_Read_UINT32(s, orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */
1152
1153 if (remaining + 1 < orderSize)
1154 {
1155 WLog_Print(up->log, WLOG_ERROR, "Stream short orderSize");
1156 return FALSE;
1157 }
1158
1159 if (!window_order_supported(update->context->settings, orderInfo.fieldFlags))
1160 {
1161 WLog_INFO(TAG, "Window order %08" PRIx32 " not supported!", orderInfo.fieldFlags);
1162 return FALSE;
1163 }
1164
1165 if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
1166 rc = update_recv_window_info_order(update, s, &orderInfo);
1167 else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY)
1168 rc = update_recv_notification_icon_info_order(update, s, &orderInfo);
1169 else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP)
1170 rc = update_recv_desktop_info_order(update, s, &orderInfo);
1171
1172 if (!rc)
1173 WLog_Print(up->log, WLOG_ERROR, "windoworder flags %08" PRIx32 " failed",
1174 orderInfo.fieldFlags);
1175
1176 return rc;
1177}