FreeRDP
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 
34 static void update_free_window_icon_info(ICON_INFO* iconInfo);
35 
36 BOOL 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 
72 BOOL 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 
96 static 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) */
106 static 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 
227 static 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 
237 static 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 
248 static 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_UINT32(s, windowState->visibleOffsetX); /* visibleOffsetX (4 bytes) */
405  Stream_Read_UINT32(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 
491 static 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 
503 static 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 
511 static void update_read_window_delete_order(wStream* s, WINDOW_ORDER_INFO* orderInfo)
512 {
513  /* window deletion event */
514 }
515 
516 static BOOL window_order_supported(const rdpSettings* settings, UINT32 fieldFlags)
517 {
518  const UINT32 mask = (WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE | WINDOW_ORDER_FIELD_RP_CONTENT |
519  WINDOW_ORDER_FIELD_ROOT_PARENT);
520  BOOL dresult = 0;
521 
522  if (!settings)
523  return FALSE;
524 
525  /* See [MS-RDPERP] 2.2.1.1.2 Window List Capability Set */
526  dresult = settings->AllowUnanouncedOrdersFromServer;
527 
528  switch (settings->RemoteWndSupportLevel)
529  {
530  case WINDOW_LEVEL_SUPPORTED_EX:
531  return TRUE;
532 
533  case WINDOW_LEVEL_SUPPORTED:
534  return ((fieldFlags & mask) == 0) || dresult;
535 
536  case WINDOW_LEVEL_NOT_SUPPORTED:
537  return dresult;
538 
539  default:
540  return dresult;
541  }
542 }
543 
544 #define DUMP_APPEND(buffer, size, ...) \
545  do \
546  { \
547  char* b = (buffer); \
548  size_t s = (size); \
549  size_t pos = strnlen(b, s); \
550  (void)_snprintf(&b[pos], s - pos, __VA_ARGS__); \
551  } while (0)
552 
553 static void dump_window_style(char* buffer, size_t bufferSize, UINT32 style)
554 {
555  DUMP_APPEND(buffer, bufferSize, " style=<0x%" PRIx32 ": ", style);
556  if (style & WS_BORDER)
557  DUMP_APPEND(buffer, bufferSize, " border");
558  if (style & WS_CAPTION)
559  DUMP_APPEND(buffer, bufferSize, " caption");
560  if (style & WS_CHILD)
561  DUMP_APPEND(buffer, bufferSize, " child");
562  if (style & WS_CHILDWINDOW)
563  DUMP_APPEND(buffer, bufferSize, " childwindow");
564  if (style & WS_CLIPCHILDREN)
565  DUMP_APPEND(buffer, bufferSize, " clipchildren");
566  if (style & WS_CLIPSIBLINGS)
567  DUMP_APPEND(buffer, bufferSize, " clipsiblings");
568  if (style & WS_DISABLED)
569  DUMP_APPEND(buffer, bufferSize, " disabled");
570  if (style & WS_DLGFRAME)
571  DUMP_APPEND(buffer, bufferSize, " dlgframe");
572  if (style & WS_GROUP)
573  DUMP_APPEND(buffer, bufferSize, " group");
574  if (style & WS_HSCROLL)
575  DUMP_APPEND(buffer, bufferSize, " hscroll");
576  if (style & WS_ICONIC)
577  DUMP_APPEND(buffer, bufferSize, " iconic");
578  if (style & WS_MAXIMIZE)
579  DUMP_APPEND(buffer, bufferSize, " maximize");
580  if (style & WS_MAXIMIZEBOX)
581  DUMP_APPEND(buffer, bufferSize, " maximizebox");
582  if (style & WS_MINIMIZE)
583  DUMP_APPEND(buffer, bufferSize, " minimize");
584  if (style & WS_MINIMIZEBOX)
585  DUMP_APPEND(buffer, bufferSize, " minimizebox");
586  if (style & WS_POPUP)
587  DUMP_APPEND(buffer, bufferSize, " popup");
588  if (style & WS_SIZEBOX)
589  DUMP_APPEND(buffer, bufferSize, " sizebox");
590  if (style & WS_SYSMENU)
591  DUMP_APPEND(buffer, bufferSize, " sysmenu");
592  if (style & WS_TABSTOP)
593  DUMP_APPEND(buffer, bufferSize, " tabstop");
594  if (style & WS_THICKFRAME)
595  DUMP_APPEND(buffer, bufferSize, " thickframe");
596  if (style & WS_VISIBLE)
597  DUMP_APPEND(buffer, bufferSize, " visible");
598  if (style & WS_VSCROLL)
599  DUMP_APPEND(buffer, bufferSize, " vscroll");
600  DUMP_APPEND(buffer, bufferSize, ">");
601 }
602 
603 static void dump_window_style_ex(char* buffer, size_t bufferSize, UINT32 extendedStyle)
604 {
605  DUMP_APPEND(buffer, bufferSize, " styleEx=<0x%" PRIx32 ": ", extendedStyle);
606  if (extendedStyle & WS_EX_ACCEPTFILES)
607  DUMP_APPEND(buffer, bufferSize, " acceptfiles");
608  if (extendedStyle & WS_EX_APPWINDOW)
609  DUMP_APPEND(buffer, bufferSize, " appwindow");
610  if (extendedStyle & WS_EX_CLIENTEDGE)
611  DUMP_APPEND(buffer, bufferSize, " clientedge");
612  if (extendedStyle & WS_EX_COMPOSITED)
613  DUMP_APPEND(buffer, bufferSize, " composited");
614  if (extendedStyle & WS_EX_CONTEXTHELP)
615  DUMP_APPEND(buffer, bufferSize, " contexthelp");
616  if (extendedStyle & WS_EX_CONTROLPARENT)
617  DUMP_APPEND(buffer, bufferSize, " controlparent");
618  if (extendedStyle & WS_EX_DLGMODALFRAME)
619  DUMP_APPEND(buffer, bufferSize, " dlgmodalframe");
620  if (extendedStyle & WS_EX_LAYERED)
621  DUMP_APPEND(buffer, bufferSize, " layered");
622  if (extendedStyle & WS_EX_LAYOUTRTL)
623  DUMP_APPEND(buffer, bufferSize, " layoutrtl");
624  if (extendedStyle & WS_EX_LEFT)
625  DUMP_APPEND(buffer, bufferSize, " left");
626  if (extendedStyle & WS_EX_LEFTSCROLLBAR)
627  DUMP_APPEND(buffer, bufferSize, " leftscrollbar");
628  if (extendedStyle & WS_EX_LTRREADING)
629  DUMP_APPEND(buffer, bufferSize, " ltrreading");
630  if (extendedStyle & WS_EX_MDICHILD)
631  DUMP_APPEND(buffer, bufferSize, " mdichild");
632  if (extendedStyle & WS_EX_NOACTIVATE)
633  DUMP_APPEND(buffer, bufferSize, " noactivate");
634  if (extendedStyle & WS_EX_NOINHERITLAYOUT)
635  DUMP_APPEND(buffer, bufferSize, " noinheritlayout");
636 #if defined(WS_EX_NOREDIRECTIONBITMAP)
637  if (extendedStyle & WS_EX_NOREDIRECTIONBITMAP)
638  DUMP_APPEND(buffer, bufferSize, " noredirectionbitmap");
639 #endif
640  if (extendedStyle & WS_EX_RIGHT)
641  DUMP_APPEND(buffer, bufferSize, " right");
642  if (extendedStyle & WS_EX_RIGHTSCROLLBAR)
643  DUMP_APPEND(buffer, bufferSize, " rightscrollbar");
644  if (extendedStyle & WS_EX_RTLREADING)
645  DUMP_APPEND(buffer, bufferSize, " rtlreading");
646  if (extendedStyle & WS_EX_STATICEDGE)
647  DUMP_APPEND(buffer, bufferSize, " staticedge");
648  if (extendedStyle & WS_EX_TOOLWINDOW)
649  DUMP_APPEND(buffer, bufferSize, " toolWindow");
650  if (extendedStyle & WS_EX_TOPMOST)
651  DUMP_APPEND(buffer, bufferSize, " topMost");
652  if (extendedStyle & WS_EX_TRANSPARENT)
653  DUMP_APPEND(buffer, bufferSize, " transparent");
654  if (extendedStyle & WS_EX_WINDOWEDGE)
655  DUMP_APPEND(buffer, bufferSize, " windowedge");
656  DUMP_APPEND(buffer, bufferSize, ">");
657 }
658 
659 static void dump_window_state_order(wLog* log, const char* msg, const WINDOW_ORDER_INFO* order,
660  const WINDOW_STATE_ORDER* state)
661 {
662  char buffer[3000] = { 0 };
663  const size_t bufferSize = sizeof(buffer) - 1;
664 
665  (void)_snprintf(buffer, bufferSize, "%s windowId=%" PRIu32 "", msg, order->windowId);
666 
667  if (order->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
668  DUMP_APPEND(buffer, bufferSize, " owner=%" PRIu32 "", state->ownerWindowId);
669  if (order->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
670  {
671  dump_window_style(buffer, bufferSize, state->style);
672  dump_window_style_ex(buffer, bufferSize, state->extendedStyle);
673  }
674 
675  if (order->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
676  {
677  const char* showStr = NULL;
678  switch (state->showState)
679  {
680  case 0:
681  showStr = "hidden";
682  break;
683  case 2:
684  showStr = "minimized";
685  break;
686  case 3:
687  showStr = "maximized";
688  break;
689  case 5:
690  showStr = "show";
691  break;
692  default:
693  showStr = "<unknown>";
694  break;
695  }
696  DUMP_APPEND(buffer, bufferSize, " show=%s", showStr);
697  }
698 
699  if (order->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
700  {
701  char* title = rail_string_to_utf8_string(&state->titleInfo);
702  if (title)
703  {
704  DUMP_APPEND(buffer, bufferSize, " title=\"%s\"", title);
705  free(title);
706  }
707  else
708  DUMP_APPEND(buffer, bufferSize, " title=<decode failed>");
709  }
710  if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
711  DUMP_APPEND(buffer, bufferSize, " clientOffset=(%" PRId32 ",%" PRId32 ")",
712  state->clientOffsetX, state->clientOffsetY);
713  if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
714  DUMP_APPEND(buffer, bufferSize, " clientAreaWidth=%" PRIu32 " clientAreaHeight=%" PRIu32 "",
715  state->clientAreaWidth, state->clientAreaHeight);
716  if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
717  DUMP_APPEND(buffer, bufferSize,
718  " resizeMarginLeft=%" PRIu32 " resizeMarginRight=%" PRIu32 "",
719  state->resizeMarginLeft, state->resizeMarginRight);
720  if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
721  DUMP_APPEND(buffer, bufferSize,
722  " resizeMarginTop=%" PRIu32 " resizeMarginBottom=%" PRIu32 "",
723  state->resizeMarginTop, state->resizeMarginBottom);
724  if (order->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
725  DUMP_APPEND(buffer, bufferSize, " rpContent=0x%" PRIx32 "", state->RPContent);
726  if (order->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
727  DUMP_APPEND(buffer, bufferSize, " rootParent=0x%" PRIx32 "", state->rootParentHandle);
728  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
729  DUMP_APPEND(buffer, bufferSize, " windowOffset=(%" PRId32 ",%" PRId32 ")",
730  state->windowOffsetX, state->windowOffsetY);
731  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
732  DUMP_APPEND(buffer, bufferSize, " windowClientDelta=(%" PRId32 ",%" PRId32 ")",
733  state->windowClientDeltaX, state->windowClientDeltaY);
734  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
735  DUMP_APPEND(buffer, bufferSize, " windowWidth=%" PRIu32 " windowHeight=%" PRIu32 "",
736  state->windowWidth, state->windowHeight);
737 
738  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
739  {
740  DUMP_APPEND(buffer, bufferSize, " windowRects=(");
741  for (UINT32 i = 0; i < state->numWindowRects; i++)
742  {
743  DUMP_APPEND(buffer, bufferSize, "(%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ")",
744  state->windowRects[i].left, state->windowRects[i].top,
745  state->windowRects[i].right, state->windowRects[i].bottom);
746  }
747  DUMP_APPEND(buffer, bufferSize, ")");
748  }
749 
750  if (order->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
751  DUMP_APPEND(buffer, bufferSize, " visibleOffset=(%" PRId32 ",%" PRId32 ")",
752  state->visibleOffsetX, state->visibleOffsetY);
753 
754  if (order->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
755  {
756  DUMP_APPEND(buffer, bufferSize, " visibilityRects=(");
757  for (UINT32 i = 0; i < state->numVisibilityRects; i++)
758  {
759  DUMP_APPEND(buffer, bufferSize, "(%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ")",
760  state->visibilityRects[i].left, state->visibilityRects[i].top,
761  state->visibilityRects[i].right, state->visibilityRects[i].bottom);
762  }
763  DUMP_APPEND(buffer, bufferSize, ")");
764  }
765 
766  if (order->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
767  DUMP_APPEND(buffer, bufferSize, " overlayDescr");
768 
769  if (order->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
770  DUMP_APPEND(buffer, bufferSize, " iconOverlayNull");
771 
772  if (order->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
773  DUMP_APPEND(buffer, bufferSize, " taskBarButton=0x%" PRIx8 "", state->TaskbarButton);
774 
775  if (order->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
776  DUMP_APPEND(buffer, bufferSize, " enforceServerZOrder=0x%" PRIx8 "",
777  state->EnforceServerZOrder);
778  if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
779  DUMP_APPEND(buffer, bufferSize, " appBarState=0x%" PRIx8 "", state->AppBarState);
780  if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
781  {
782  const char* appBarEdgeStr = NULL;
783  switch (state->AppBarEdge)
784  {
785  case 0:
786  appBarEdgeStr = "left";
787  break;
788  case 1:
789  appBarEdgeStr = "top";
790  break;
791  case 2:
792  appBarEdgeStr = "right";
793  break;
794  case 3:
795  appBarEdgeStr = "bottom";
796  break;
797  default:
798  appBarEdgeStr = "<unknown>";
799  break;
800  }
801  DUMP_APPEND(buffer, bufferSize, " appBarEdge=%s", appBarEdgeStr);
802  }
803 
804  WLog_Print(log, WLOG_DEBUG, buffer);
805 }
806 
807 static BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s,
808  WINDOW_ORDER_INFO* orderInfo)
809 {
810  rdp_update_internal* up = update_cast(update);
811  rdpContext* context = update->context;
812  rdpWindowUpdate* window = update->window;
813 
814  BOOL result = TRUE;
815 
816  WINPR_ASSERT(s);
817  WINPR_ASSERT(context);
818  WINPR_ASSERT(window);
819  WINPR_ASSERT(orderInfo);
820 
821  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
822  return FALSE;
823 
824  Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */
825 
826  if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
827  {
828  WINDOW_ICON_ORDER window_icon = { 0 };
829  result = update_read_window_icon_order(s, orderInfo, &window_icon);
830 
831  if (result)
832  {
833  WLog_Print(up->log, WLOG_DEBUG, "WindowIcon windowId=0x%" PRIx32 "",
834  orderInfo->windowId);
835  IFCALLRET(window->WindowIcon, result, context, orderInfo, &window_icon);
836  }
837 
838  update_free_window_icon_info(window_icon.iconInfo);
839  free(window_icon.iconInfo);
840  }
841  else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
842  {
843  WINDOW_CACHED_ICON_ORDER window_cached_icon = { 0 };
844  result = update_read_window_cached_icon_order(s, orderInfo, &window_cached_icon);
845 
846  if (result)
847  {
848  WLog_Print(up->log, WLOG_DEBUG, "WindowCachedIcon windowId=0x%" PRIx32 "",
849  orderInfo->windowId);
850  IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window_cached_icon);
851  }
852  }
853  else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
854  {
855  update_read_window_delete_order(s, orderInfo);
856  WLog_Print(up->log, WLOG_DEBUG, "WindowDelete windowId=0x%" PRIx32 "", orderInfo->windowId);
857  IFCALLRET(window->WindowDelete, result, context, orderInfo);
858  }
859  else
860  {
861  WINDOW_STATE_ORDER windowState = { 0 };
862  result = update_read_window_state_order(s, orderInfo, &windowState);
863 
864  if (result)
865  {
866  if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
867  {
868  dump_window_state_order(up->log, "WindowCreate", orderInfo, &windowState);
869  IFCALLRET(window->WindowCreate, result, context, orderInfo, &windowState);
870  }
871  else
872  {
873  dump_window_state_order(up->log, "WindowUpdate", orderInfo, &windowState);
874  IFCALLRET(window->WindowUpdate, result, context, orderInfo, &windowState);
875  }
876 
877  update_free_window_state(&windowState);
878  }
879  }
880 
881  return result;
882 }
883 
884 static void update_notify_icon_state_order_free(NOTIFY_ICON_STATE_ORDER* notify)
885 {
886  free(notify->toolTip.string);
887  free(notify->infoTip.text.string);
888  free(notify->infoTip.title.string);
889  update_free_window_icon_info(&notify->icon);
890  memset(notify, 0, sizeof(NOTIFY_ICON_STATE_ORDER));
891 }
892 
893 static BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
894  NOTIFY_ICON_STATE_ORDER* notify_icon_state)
895 {
896  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
897  {
898  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
899  return FALSE;
900 
901  Stream_Read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */
902  }
903 
904  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
905  {
906  if (!rail_read_unicode_string(s,
907  &notify_icon_state->toolTip)) /* toolTip (UNICODE_STRING) */
908  return FALSE;
909  }
910 
911  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
912  {
913  if (!update_read_notify_icon_infotip(
914  s, &notify_icon_state->infoTip)) /* infoTip (NOTIFY_ICON_INFOTIP) */
915  return FALSE;
916  }
917 
918  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
919  {
920  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
921  return FALSE;
922 
923  Stream_Read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */
924  }
925 
926  if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
927  {
928  if (!update_read_icon_info(s, &notify_icon_state->icon)) /* icon (ICON_INFO) */
929  return FALSE;
930  }
931 
932  if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
933  {
934  if (!update_read_cached_icon_info(
935  s, &notify_icon_state->cachedIcon)) /* cachedIcon (CACHED_ICON_INFO) */
936  return FALSE;
937  }
938 
939  return TRUE;
940 }
941 
942 static void update_read_notification_icon_delete_order(wStream* s, WINDOW_ORDER_INFO* orderInfo)
943 {
944  /* notification icon deletion event */
945 }
946 
947 static BOOL update_recv_notification_icon_info_order(rdpUpdate* update, wStream* s,
948  WINDOW_ORDER_INFO* orderInfo)
949 {
950  rdp_update_internal* up = update_cast(update);
951  rdpContext* context = update->context;
952  rdpWindowUpdate* window = update->window;
953  BOOL result = TRUE;
954 
955  WINPR_ASSERT(s);
956  WINPR_ASSERT(orderInfo);
957  WINPR_ASSERT(context);
958  WINPR_ASSERT(window);
959 
960  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
961  return FALSE;
962 
963  Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */
964  Stream_Read_UINT32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */
965 
966  if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
967  {
968  update_read_notification_icon_delete_order(s, orderInfo);
969  WLog_Print(up->log, WLOG_DEBUG, "NotifyIconDelete");
970  IFCALLRET(window->NotifyIconDelete, result, context, orderInfo);
971  }
972  else
973  {
974  NOTIFY_ICON_STATE_ORDER notify_icon_state = { 0 };
975  result = update_read_notification_icon_state_order(s, orderInfo, &notify_icon_state);
976 
977  if (!result)
978  goto fail;
979 
980  if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
981  {
982  WLog_Print(up->log, WLOG_DEBUG, "NotifyIconCreate");
983  IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, &notify_icon_state);
984  }
985  else
986  {
987  WLog_Print(up->log, WLOG_DEBUG, "NotifyIconUpdate");
988  IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, &notify_icon_state);
989  }
990  fail:
991  update_notify_icon_state_order_free(&notify_icon_state);
992  }
993 
994  return result;
995 }
996 
997 static BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
998  MONITORED_DESKTOP_ORDER* monitored_desktop)
999 {
1000  int size = 0;
1001 
1002  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1003  {
1004  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
1005  return FALSE;
1006 
1007  Stream_Read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */
1008  }
1009 
1010  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1011  {
1012  UINT32* newid = NULL;
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  return FALSE;
1021 
1022  if (monitored_desktop->numWindowIds > 0)
1023  {
1024  size = sizeof(UINT32) * monitored_desktop->numWindowIds;
1025  newid = (UINT32*)realloc(monitored_desktop->windowIds, size);
1026 
1027  if (!newid)
1028  {
1029  free(monitored_desktop->windowIds);
1030  monitored_desktop->windowIds = NULL;
1031  return FALSE;
1032  }
1033 
1034  monitored_desktop->windowIds = newid;
1035 
1036  /* windowIds */
1037  for (UINT32 i = 0; i < monitored_desktop->numWindowIds; i++)
1038  {
1039  Stream_Read_UINT32(s, monitored_desktop->windowIds[i]);
1040  }
1041  }
1042  }
1043 
1044  return TRUE;
1045 }
1046 
1047 static void update_read_desktop_non_monitored_order(wStream* s, WINDOW_ORDER_INFO* orderInfo)
1048 {
1049  /* non-monitored desktop notification event */
1050 }
1051 
1052 static void dump_monitored_desktop(wLog* log, const char* msg, const WINDOW_ORDER_INFO* orderInfo,
1053  const MONITORED_DESKTOP_ORDER* monitored)
1054 {
1055  char buffer[1000] = { 0 };
1056  const size_t bufferSize = sizeof(buffer) - 1;
1057 
1058  DUMP_APPEND(buffer, bufferSize, "%s", msg);
1059 
1060  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
1061  DUMP_APPEND(buffer, bufferSize, " activeWindowId=0x%" PRIx32 "", monitored->activeWindowId);
1062 
1063  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
1064  {
1065  DUMP_APPEND(buffer, bufferSize, " windows=(");
1066  for (UINT32 i = 0; i < monitored->numWindowIds; i++)
1067  {
1068  DUMP_APPEND(buffer, bufferSize, "0x%" PRIx32 ",", monitored->windowIds[i]);
1069  }
1070  DUMP_APPEND(buffer, bufferSize, ")");
1071  }
1072  WLog_Print(log, WLOG_DEBUG, buffer);
1073 }
1074 
1075 static BOOL update_recv_desktop_info_order(rdpUpdate* update, wStream* s,
1076  WINDOW_ORDER_INFO* orderInfo)
1077 {
1078  rdp_update_internal* up = update_cast(update);
1079  rdpContext* context = update->context;
1080  rdpWindowUpdate* window = update->window;
1081  BOOL result = TRUE;
1082 
1083  WINPR_ASSERT(s);
1084  WINPR_ASSERT(orderInfo);
1085  WINPR_ASSERT(context);
1086  WINPR_ASSERT(window);
1087 
1088  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE)
1089  {
1090  update_read_desktop_non_monitored_order(s, orderInfo);
1091  WLog_Print(up->log, WLOG_DEBUG, "NonMonitoredDesktop, windowId=0x%" PRIx32 "",
1092  orderInfo->windowId);
1093  IFCALLRET(window->NonMonitoredDesktop, result, context, orderInfo);
1094  }
1095  else
1096  {
1097  MONITORED_DESKTOP_ORDER monitored_desktop = { 0 };
1098  result = update_read_desktop_actively_monitored_order(s, orderInfo, &monitored_desktop);
1099 
1100  if (result)
1101  {
1102  dump_monitored_desktop(up->log, "ActivelyMonitoredDesktop", orderInfo,
1103  &monitored_desktop);
1104  IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &monitored_desktop);
1105  }
1106 
1107  free(monitored_desktop.windowIds);
1108  }
1109 
1110  return result;
1111 }
1112 
1113 void update_free_window_icon_info(ICON_INFO* iconInfo)
1114 {
1115  if (!iconInfo)
1116  return;
1117 
1118  free(iconInfo->bitsColor);
1119  iconInfo->bitsColor = NULL;
1120  free(iconInfo->bitsMask);
1121  iconInfo->bitsMask = NULL;
1122  free(iconInfo->colorTable);
1123  iconInfo->colorTable = NULL;
1124 }
1125 
1126 BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s)
1127 {
1128  BOOL rc = TRUE;
1129  size_t remaining = 0;
1130  UINT16 orderSize = 0;
1131  WINDOW_ORDER_INFO orderInfo = { 0 };
1132  rdp_update_internal* up = update_cast(update);
1133 
1134  remaining = Stream_GetRemainingLength(s);
1135 
1136  if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1137  return FALSE;
1138 
1139  Stream_Read_UINT16(s, orderSize); /* orderSize (2 bytes) */
1140  Stream_Read_UINT32(s, orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */
1141 
1142  if (remaining + 1 < orderSize)
1143  {
1144  WLog_Print(up->log, WLOG_ERROR, "Stream short orderSize");
1145  return FALSE;
1146  }
1147 
1148  if (!window_order_supported(update->context->settings, orderInfo.fieldFlags))
1149  {
1150  WLog_INFO(TAG, "Window order %08" PRIx32 " not supported!", orderInfo.fieldFlags);
1151  return FALSE;
1152  }
1153 
1154  if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
1155  rc = update_recv_window_info_order(update, s, &orderInfo);
1156  else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY)
1157  rc = update_recv_notification_icon_info_order(update, s, &orderInfo);
1158  else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP)
1159  rc = update_recv_desktop_info_order(update, s, &orderInfo);
1160 
1161  if (!rc)
1162  WLog_Print(up->log, WLOG_ERROR, "windoworder flags %08" PRIx32 " failed",
1163  orderInfo.fieldFlags);
1164 
1165  return rc;
1166 }