Coverage Report

Created: 2024-05-20 06:11

/src/FreeRDP/libfreerdp/core/window.c
Line
Count
Source (jump to first uncovered line)
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Windowing Alternate Secondary Orders
4
 *
5
 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2011 Roman Barabanov <romanbarabanov@gmail.com>
7
 *
8
 * Licensed under the Apache License, Version 2.0 (the "License");
9
 * you may not use this file except in compliance with the License.
10
 * You may obtain a copy of the License at
11
 *
12
 *     http://www.apache.org/licenses/LICENSE-2.0
13
 *
14
 * Unless required by applicable law or agreed to in writing, software
15
 * distributed under the License is distributed on an "AS IS" BASIS,
16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
 * See the License for the specific language governing permissions and
18
 * limitations under the License.
19
 */
20
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
0
{
38
0
  UINT16 new_len = 0;
39
0
  BYTE* new_str = NULL;
40
41
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
42
0
    return FALSE;
43
44
0
  Stream_Read_UINT16(s, new_len); /* cbString (2 bytes) */
45
46
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, new_len))
47
0
    return FALSE;
48
49
0
  if (!new_len)
50
0
  {
51
0
    free(unicode_string->string);
52
0
    unicode_string->string = NULL;
53
0
    unicode_string->length = 0;
54
0
    return TRUE;
55
0
  }
56
57
0
  new_str = (BYTE*)realloc(unicode_string->string, new_len);
58
59
0
  if (!new_str)
60
0
  {
61
0
    free(unicode_string->string);
62
0
    unicode_string->string = NULL;
63
0
    return FALSE;
64
0
  }
65
66
0
  unicode_string->string = new_str;
67
0
  unicode_string->length = new_len;
68
0
  Stream_Read(s, unicode_string->string, unicode_string->length);
69
0
  return TRUE;
70
0
}
71
72
BOOL utf8_string_to_rail_string(const char* string, RAIL_UNICODE_STRING* unicode_string)
73
0
{
74
0
  WCHAR* buffer = NULL;
75
0
  size_t len = 0;
76
0
  free(unicode_string->string);
77
0
  unicode_string->string = NULL;
78
0
  unicode_string->length = 0;
79
80
0
  if (!string || strlen(string) < 1)
81
0
    return TRUE;
82
83
0
  buffer = ConvertUtf8ToWCharAlloc(string, &len);
84
85
0
  if (!buffer || (len * sizeof(WCHAR) > UINT16_MAX))
86
0
  {
87
0
    free(buffer);
88
0
    return FALSE;
89
0
  }
90
91
0
  unicode_string->string = (BYTE*)buffer;
92
0
  unicode_string->length = (UINT16)len * sizeof(WCHAR);
93
0
  return TRUE;
94
0
}
95
96
/* See [MS-RDPERP] 2.2.1.2.3 Icon Info (TS_ICON_INFO) */
97
static BOOL update_read_icon_info(wStream* s, ICON_INFO* iconInfo)
98
0
{
99
0
  BYTE* newBitMask = NULL;
100
101
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
102
0
    return FALSE;
103
104
0
  Stream_Read_UINT16(s, iconInfo->cacheEntry); /* cacheEntry (2 bytes) */
105
0
  Stream_Read_UINT8(s, iconInfo->cacheId);     /* cacheId (1 byte) */
106
0
  Stream_Read_UINT8(s, iconInfo->bpp);         /* bpp (1 byte) */
107
108
0
  if ((iconInfo->bpp < 1) || (iconInfo->bpp > 32))
109
0
  {
110
0
    WLog_ERR(TAG, "invalid bpp value %" PRIu32 "", iconInfo->bpp);
111
0
    return FALSE;
112
0
  }
113
114
0
  Stream_Read_UINT16(s, iconInfo->width);  /* width (2 bytes) */
115
0
  Stream_Read_UINT16(s, iconInfo->height); /* height (2 bytes) */
116
117
  /* cbColorTable is only present when bpp is 1, 4 or 8 */
118
0
  switch (iconInfo->bpp)
119
0
  {
120
0
    case 1:
121
0
    case 4:
122
0
    case 8:
123
0
      if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
124
0
        return FALSE;
125
126
0
      Stream_Read_UINT16(s, iconInfo->cbColorTable); /* cbColorTable (2 bytes) */
127
0
      break;
128
129
0
    default:
130
0
      iconInfo->cbColorTable = 0;
131
0
      break;
132
0
  }
133
134
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
135
0
    return FALSE;
136
137
0
  Stream_Read_UINT16(s, iconInfo->cbBitsMask);  /* cbBitsMask (2 bytes) */
138
0
  Stream_Read_UINT16(s, iconInfo->cbBitsColor); /* cbBitsColor (2 bytes) */
139
140
  /* bitsMask */
141
0
  if (iconInfo->cbBitsMask > 0)
142
0
  {
143
0
    newBitMask = (BYTE*)realloc(iconInfo->bitsMask, iconInfo->cbBitsMask);
144
145
0
    if (!newBitMask)
146
0
    {
147
0
      free(iconInfo->bitsMask);
148
0
      iconInfo->bitsMask = NULL;
149
0
      return FALSE;
150
0
    }
151
152
0
    iconInfo->bitsMask = newBitMask;
153
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsMask))
154
0
      return FALSE;
155
0
    Stream_Read(s, iconInfo->bitsMask, iconInfo->cbBitsMask);
156
0
  }
157
0
  else
158
0
  {
159
0
    free(iconInfo->bitsMask);
160
0
    iconInfo->bitsMask = NULL;
161
0
    iconInfo->cbBitsMask = 0;
162
0
  }
163
164
  /* colorTable */
165
0
  if (iconInfo->cbColorTable > 0)
166
0
  {
167
0
    BYTE* new_tab = NULL;
168
0
    new_tab = (BYTE*)realloc(iconInfo->colorTable, iconInfo->cbColorTable);
169
170
0
    if (!new_tab)
171
0
    {
172
0
      free(iconInfo->colorTable);
173
0
      iconInfo->colorTable = NULL;
174
0
      return FALSE;
175
0
    }
176
177
0
    iconInfo->colorTable = new_tab;
178
0
  }
179
0
  else
180
0
  {
181
0
    free(iconInfo->colorTable);
182
0
    iconInfo->colorTable = NULL;
183
0
  }
184
185
0
  if (iconInfo->colorTable)
186
0
  {
187
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbColorTable))
188
0
      return FALSE;
189
0
    Stream_Read(s, iconInfo->colorTable, iconInfo->cbColorTable);
190
0
  }
191
192
  /* bitsColor */
193
0
  if (iconInfo->cbBitsColor > 0)
194
0
  {
195
0
    newBitMask = (BYTE*)realloc(iconInfo->bitsColor, iconInfo->cbBitsColor);
196
197
0
    if (!newBitMask)
198
0
    {
199
0
      free(iconInfo->bitsColor);
200
0
      iconInfo->bitsColor = NULL;
201
0
      return FALSE;
202
0
    }
203
204
0
    iconInfo->bitsColor = newBitMask;
205
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, iconInfo->cbBitsColor))
206
0
      return FALSE;
207
0
    Stream_Read(s, iconInfo->bitsColor, iconInfo->cbBitsColor);
208
0
  }
209
0
  else
210
0
  {
211
0
    free(iconInfo->bitsColor);
212
0
    iconInfo->bitsColor = NULL;
213
0
    iconInfo->cbBitsColor = 0;
214
0
  }
215
0
  return TRUE;
216
0
}
217
218
static BOOL update_read_cached_icon_info(wStream* s, CACHED_ICON_INFO* cachedIconInfo)
219
0
{
220
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 3))
221
0
    return FALSE;
222
223
0
  Stream_Read_UINT16(s, cachedIconInfo->cacheEntry); /* cacheEntry (2 bytes) */
224
0
  Stream_Read_UINT8(s, cachedIconInfo->cacheId);     /* cacheId (1 byte) */
225
0
  return TRUE;
226
0
}
227
228
static BOOL update_read_notify_icon_infotip(wStream* s, NOTIFY_ICON_INFOTIP* notifyIconInfoTip)
229
0
{
230
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
231
0
    return FALSE;
232
233
0
  Stream_Read_UINT32(s, notifyIconInfoTip->timeout);              /* timeout (4 bytes) */
234
0
  Stream_Read_UINT32(s, notifyIconInfoTip->flags);                /* infoFlags (4 bytes) */
235
0
  return rail_read_unicode_string(s, &notifyIconInfoTip->text) && /* infoTipText */
236
0
         rail_read_unicode_string(s, &notifyIconInfoTip->title);  /* title */
237
0
}
238
239
static BOOL update_read_window_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
240
                                           WINDOW_STATE_ORDER* windowState)
241
0
{
242
0
  size_t size = 0;
243
0
  RECTANGLE_16* newRect = NULL;
244
245
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
246
0
  {
247
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
248
0
      return FALSE;
249
250
0
    Stream_Read_UINT32(s, windowState->ownerWindowId); /* ownerWindowId (4 bytes) */
251
0
  }
252
253
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
254
0
  {
255
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
256
0
      return FALSE;
257
258
0
    Stream_Read_UINT32(s, windowState->style);         /* style (4 bytes) */
259
0
    Stream_Read_UINT32(s, windowState->extendedStyle); /* extendedStyle (4 bytes) */
260
0
  }
261
262
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
263
0
  {
264
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
265
0
      return FALSE;
266
267
0
    Stream_Read_UINT8(s, windowState->showState); /* showState (1 byte) */
268
0
  }
269
270
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
271
0
  {
272
0
    if (!rail_read_unicode_string(s, &windowState->titleInfo)) /* titleInfo */
273
0
      return FALSE;
274
0
  }
275
276
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
277
0
  {
278
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
279
0
      return FALSE;
280
281
0
    Stream_Read_INT32(s, windowState->clientOffsetX); /* clientOffsetX (4 bytes) */
282
0
    Stream_Read_INT32(s, windowState->clientOffsetY); /* clientOffsetY (4 bytes) */
283
0
  }
284
285
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
286
0
  {
287
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
288
0
      return FALSE;
289
290
0
    Stream_Read_UINT32(s, windowState->clientAreaWidth);  /* clientAreaWidth (4 bytes) */
291
0
    Stream_Read_UINT32(s, windowState->clientAreaHeight); /* clientAreaHeight (4 bytes) */
292
0
  }
293
294
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
295
0
  {
296
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
297
0
      return FALSE;
298
299
0
    Stream_Read_UINT32(s, windowState->resizeMarginLeft);
300
0
    Stream_Read_UINT32(s, windowState->resizeMarginRight);
301
0
  }
302
303
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
304
0
  {
305
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
306
0
      return FALSE;
307
308
0
    Stream_Read_UINT32(s, windowState->resizeMarginTop);
309
0
    Stream_Read_UINT32(s, windowState->resizeMarginBottom);
310
0
  }
311
312
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
313
0
  {
314
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
315
0
      return FALSE;
316
317
0
    Stream_Read_UINT8(s, windowState->RPContent); /* RPContent (1 byte) */
318
0
  }
319
320
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
321
0
  {
322
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
323
0
      return FALSE;
324
325
0
    Stream_Read_UINT32(s, windowState->rootParentHandle); /* rootParentHandle (4 bytes) */
326
0
  }
327
328
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
329
0
  {
330
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
331
0
      return FALSE;
332
333
0
    Stream_Read_INT32(s, windowState->windowOffsetX); /* windowOffsetX (4 bytes) */
334
0
    Stream_Read_INT32(s, windowState->windowOffsetY); /* windowOffsetY (4 bytes) */
335
0
  }
336
337
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
338
0
  {
339
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
340
0
      return FALSE;
341
342
0
    Stream_Read_INT32(s, windowState->windowClientDeltaX); /* windowClientDeltaX (4 bytes) */
343
0
    Stream_Read_INT32(s, windowState->windowClientDeltaY); /* windowClientDeltaY (4 bytes) */
344
0
  }
345
346
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
347
0
  {
348
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
349
0
      return FALSE;
350
351
0
    Stream_Read_UINT32(s, windowState->windowWidth);  /* windowWidth (4 bytes) */
352
0
    Stream_Read_UINT32(s, windowState->windowHeight); /* windowHeight (4 bytes) */
353
0
  }
354
355
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
356
0
  {
357
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
358
0
      return FALSE;
359
360
0
    Stream_Read_UINT16(s, windowState->numWindowRects); /* numWindowRects (2 bytes) */
361
362
0
    if (windowState->numWindowRects > 0)
363
0
    {
364
0
      size = sizeof(RECTANGLE_16) * windowState->numWindowRects;
365
0
      newRect = (RECTANGLE_16*)realloc(windowState->windowRects, size);
366
367
0
      if (!newRect)
368
0
      {
369
0
        free(windowState->windowRects);
370
0
        windowState->windowRects = NULL;
371
0
        return FALSE;
372
0
      }
373
374
0
      windowState->windowRects = newRect;
375
376
0
      if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numWindowRects, 8ull))
377
0
        return FALSE;
378
379
      /* windowRects */
380
0
      for (UINT32 i = 0; i < windowState->numWindowRects; i++)
381
0
      {
382
0
        Stream_Read_UINT16(s, windowState->windowRects[i].left);   /* left (2 bytes) */
383
0
        Stream_Read_UINT16(s, windowState->windowRects[i].top);    /* top (2 bytes) */
384
0
        Stream_Read_UINT16(s, windowState->windowRects[i].right);  /* right (2 bytes) */
385
0
        Stream_Read_UINT16(s, windowState->windowRects[i].bottom); /* bottom (2 bytes) */
386
0
      }
387
0
    }
388
0
  }
389
390
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
391
0
  {
392
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
393
0
      return FALSE;
394
395
0
    Stream_Read_UINT32(s, windowState->visibleOffsetX); /* visibleOffsetX (4 bytes) */
396
0
    Stream_Read_UINT32(s, windowState->visibleOffsetY); /* visibleOffsetY (4 bytes) */
397
0
  }
398
399
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
400
0
  {
401
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 2))
402
0
      return FALSE;
403
404
0
    Stream_Read_UINT16(s, windowState->numVisibilityRects); /* numVisibilityRects (2 bytes) */
405
406
0
    if (windowState->numVisibilityRects != 0)
407
0
    {
408
0
      size = sizeof(RECTANGLE_16) * windowState->numVisibilityRects;
409
0
      newRect = (RECTANGLE_16*)realloc(windowState->visibilityRects, size);
410
411
0
      if (!newRect)
412
0
      {
413
0
        free(windowState->visibilityRects);
414
0
        windowState->visibilityRects = NULL;
415
0
        return FALSE;
416
0
      }
417
418
0
      windowState->visibilityRects = newRect;
419
420
0
      if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, windowState->numVisibilityRects,
421
0
                                                  8ull))
422
0
        return FALSE;
423
424
      /* visibilityRects */
425
0
      for (UINT32 i = 0; i < windowState->numVisibilityRects; i++)
426
0
      {
427
0
        Stream_Read_UINT16(s, windowState->visibilityRects[i].left);  /* left (2 bytes) */
428
0
        Stream_Read_UINT16(s, windowState->visibilityRects[i].top);   /* top (2 bytes) */
429
0
        Stream_Read_UINT16(s, windowState->visibilityRects[i].right); /* right (2 bytes) */
430
0
        Stream_Read_UINT16(s,
431
0
                           windowState->visibilityRects[i].bottom); /* bottom (2 bytes) */
432
0
      }
433
0
    }
434
0
  }
435
436
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
437
0
  {
438
0
    if (!rail_read_unicode_string(s, &windowState->OverlayDescription))
439
0
      return FALSE;
440
0
  }
441
442
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
443
0
  {
444
    /* no data to be read here */
445
0
  }
446
447
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
448
0
  {
449
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
450
0
      return FALSE;
451
452
0
    Stream_Read_UINT8(s, windowState->TaskbarButton);
453
0
  }
454
455
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
456
0
  {
457
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
458
0
      return FALSE;
459
460
0
    Stream_Read_UINT8(s, windowState->EnforceServerZOrder);
461
0
  }
462
463
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
464
0
  {
465
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
466
0
      return FALSE;
467
468
0
    Stream_Read_UINT8(s, windowState->AppBarState);
469
0
  }
470
471
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
472
0
  {
473
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
474
0
      return FALSE;
475
476
0
    Stream_Read_UINT8(s, windowState->AppBarEdge);
477
0
  }
478
479
0
  return TRUE;
480
0
}
481
482
static BOOL update_read_window_icon_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
483
                                          WINDOW_ICON_ORDER* window_icon)
484
0
{
485
0
  WINPR_UNUSED(orderInfo);
486
0
  window_icon->iconInfo = (ICON_INFO*)calloc(1, sizeof(ICON_INFO));
487
488
0
  if (!window_icon->iconInfo)
489
0
    return FALSE;
490
491
0
  return update_read_icon_info(s, window_icon->iconInfo); /* iconInfo (ICON_INFO) */
492
0
}
493
494
static BOOL update_read_window_cached_icon_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
495
                                                 WINDOW_CACHED_ICON_ORDER* window_cached_icon)
496
0
{
497
0
  WINPR_UNUSED(orderInfo);
498
0
  return update_read_cached_icon_info(
499
0
      s, &window_cached_icon->cachedIcon); /* cachedIcon (CACHED_ICON_INFO) */
500
0
}
501
502
static void update_read_window_delete_order(wStream* s, WINDOW_ORDER_INFO* orderInfo)
503
0
{
504
  /* window deletion event */
505
0
}
506
507
static BOOL window_order_supported(const rdpSettings* settings, UINT32 fieldFlags)
508
6.20k
{
509
6.20k
  const UINT32 mask = (WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE | WINDOW_ORDER_FIELD_RP_CONTENT |
510
6.20k
                       WINDOW_ORDER_FIELD_ROOT_PARENT);
511
6.20k
  BOOL dresult = 0;
512
513
6.20k
  if (!settings)
514
0
    return FALSE;
515
516
  /* See [MS-RDPERP] 2.2.1.1.2 Window List Capability Set */
517
6.20k
  dresult = settings->AllowUnanouncedOrdersFromServer;
518
519
6.20k
  switch (settings->RemoteWndSupportLevel)
520
6.20k
  {
521
0
    case WINDOW_LEVEL_SUPPORTED_EX:
522
0
      return TRUE;
523
524
0
    case WINDOW_LEVEL_SUPPORTED:
525
0
      return ((fieldFlags & mask) == 0) || dresult;
526
527
0
    case WINDOW_LEVEL_NOT_SUPPORTED:
528
0
      return dresult;
529
530
6.20k
    default:
531
6.20k
      return dresult;
532
6.20k
  }
533
6.20k
}
534
535
#define DUMP_APPEND(buffer, size, ...)            \
536
0
  do                                            \
537
0
  {                                             \
538
0
    char* b = (buffer);                       \
539
0
    size_t s = (size);                        \
540
0
    size_t pos = strnlen(b, s);               \
541
0
    _snprintf(&b[pos], s - pos, __VA_ARGS__); \
542
0
  } while (0)
543
544
static void dump_window_state_order(wLog* log, const char* msg, const WINDOW_ORDER_INFO* order,
545
                                    const WINDOW_STATE_ORDER* state)
546
0
{
547
0
  char buffer[3000] = { 0 };
548
0
  const size_t bufferSize = sizeof(buffer) - 1;
549
550
0
  _snprintf(buffer, bufferSize, "%s windowId=0x%" PRIu32 "", msg, order->windowId);
551
552
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_OWNER)
553
0
    DUMP_APPEND(buffer, bufferSize, " owner=0x%" PRIx32 "", state->ownerWindowId);
554
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_STYLE)
555
0
  {
556
0
    DUMP_APPEND(buffer, bufferSize, " [ex]style=<0x%" PRIx32 ", 0x%" PRIx32 "", state->style,
557
0
                state->extendedStyle);
558
0
    if (state->style & WS_POPUP)
559
0
      DUMP_APPEND(buffer, bufferSize, " popup");
560
0
    if (state->style & WS_VISIBLE)
561
0
      DUMP_APPEND(buffer, bufferSize, " visible");
562
0
    if (state->style & WS_THICKFRAME)
563
0
      DUMP_APPEND(buffer, bufferSize, " thickframe");
564
0
    if (state->style & WS_BORDER)
565
0
      DUMP_APPEND(buffer, bufferSize, " border");
566
0
    if (state->style & WS_CAPTION)
567
0
      DUMP_APPEND(buffer, bufferSize, " caption");
568
569
0
    if (state->extendedStyle & WS_EX_NOACTIVATE)
570
0
      DUMP_APPEND(buffer, bufferSize, " noactivate");
571
0
    if (state->extendedStyle & WS_EX_TOOLWINDOW)
572
0
      DUMP_APPEND(buffer, bufferSize, " toolWindow");
573
0
    if (state->extendedStyle & WS_EX_TOPMOST)
574
0
      DUMP_APPEND(buffer, bufferSize, " topMost");
575
576
0
    DUMP_APPEND(buffer, bufferSize, ">");
577
0
  }
578
579
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_SHOW)
580
0
  {
581
0
    const char* showStr = NULL;
582
0
    switch (state->showState)
583
0
    {
584
0
      case 0:
585
0
        showStr = "hidden";
586
0
        break;
587
0
      case 2:
588
0
        showStr = "minimized";
589
0
        break;
590
0
      case 3:
591
0
        showStr = "maximized";
592
0
        break;
593
0
      case 5:
594
0
        showStr = "current";
595
0
        break;
596
0
      default:
597
0
        showStr = "<unknown>";
598
0
        break;
599
0
    }
600
0
    DUMP_APPEND(buffer, bufferSize, " show=%s", showStr);
601
0
  }
602
603
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
604
0
    DUMP_APPEND(buffer, bufferSize, " title");
605
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET)
606
0
    DUMP_APPEND(buffer, bufferSize, " clientOffset=(%" PRId32 ",%" PRId32 ")",
607
0
                state->clientOffsetX, state->clientOffsetY);
608
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE)
609
0
    DUMP_APPEND(buffer, bufferSize, " clientAreaWidth=%" PRIu32 " clientAreaHeight=%" PRIu32 "",
610
0
                state->clientAreaWidth, state->clientAreaHeight);
611
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_X)
612
0
    DUMP_APPEND(buffer, bufferSize,
613
0
                " resizeMarginLeft=%" PRIu32 " resizeMarginRight=%" PRIu32 "",
614
0
                state->resizeMarginLeft, state->resizeMarginRight);
615
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_RESIZE_MARGIN_Y)
616
0
    DUMP_APPEND(buffer, bufferSize,
617
0
                " resizeMarginTop=%" PRIu32 " resizeMarginBottom=%" PRIu32 "",
618
0
                state->resizeMarginTop, state->resizeMarginBottom);
619
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_RP_CONTENT)
620
0
    DUMP_APPEND(buffer, bufferSize, " rpContent=0x%" PRIx32 "", state->RPContent);
621
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_ROOT_PARENT)
622
0
    DUMP_APPEND(buffer, bufferSize, " rootParent=0x%" PRIx32 "", state->rootParentHandle);
623
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET)
624
0
    DUMP_APPEND(buffer, bufferSize, " windowOffset=(%" PRId32 ",%" PRId32 ")",
625
0
                state->windowOffsetX, state->windowOffsetY);
626
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA)
627
0
    DUMP_APPEND(buffer, bufferSize, " windowClientDelta=(%" PRId32 ",%" PRId32 ")",
628
0
                state->windowClientDeltaX, state->windowClientDeltaY);
629
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)
630
0
    DUMP_APPEND(buffer, bufferSize, " windowWidth=%" PRIu32 " windowHeight=%" PRIu32 "",
631
0
                state->windowWidth, state->windowHeight);
632
633
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
634
0
  {
635
0
    DUMP_APPEND(buffer, bufferSize, " windowRects=(");
636
0
    for (UINT32 i = 0; i < state->numWindowRects; i++)
637
0
    {
638
0
      DUMP_APPEND(buffer, bufferSize, "(%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ")",
639
0
                  state->windowRects[i].left, state->windowRects[i].top,
640
0
                  state->windowRects[i].right, state->windowRects[i].bottom);
641
0
    }
642
0
    DUMP_APPEND(buffer, bufferSize, ")");
643
0
  }
644
645
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET)
646
0
    DUMP_APPEND(buffer, bufferSize, " visibleOffset=(%" PRId32 ",%" PRId32 ")",
647
0
                state->visibleOffsetX, state->visibleOffsetY);
648
649
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
650
0
  {
651
0
    DUMP_APPEND(buffer, bufferSize, " visibilityRects=(");
652
0
    for (UINT32 i = 0; i < state->numVisibilityRects; i++)
653
0
    {
654
0
      DUMP_APPEND(buffer, bufferSize, "(%" PRIu16 ",%" PRIu16 ",%" PRIu16 ",%" PRIu16 ")",
655
0
                  state->visibilityRects[i].left, state->visibilityRects[i].top,
656
0
                  state->visibilityRects[i].right, state->visibilityRects[i].bottom);
657
0
    }
658
0
    DUMP_APPEND(buffer, bufferSize, ")");
659
0
  }
660
661
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_OVERLAY_DESCRIPTION)
662
0
    DUMP_APPEND(buffer, bufferSize, " overlayDescr");
663
664
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_ICON_OVERLAY_NULL)
665
0
    DUMP_APPEND(buffer, bufferSize, " iconOverlayNull");
666
667
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_TASKBAR_BUTTON)
668
0
    DUMP_APPEND(buffer, bufferSize, " taskBarButton=0x%" PRIx8 "", state->TaskbarButton);
669
670
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_ENFORCE_SERVER_ZORDER)
671
0
    DUMP_APPEND(buffer, bufferSize, " enforceServerZOrder=0x%" PRIx8 "",
672
0
                state->EnforceServerZOrder);
673
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_STATE)
674
0
    DUMP_APPEND(buffer, bufferSize, " appBarState=0x%" PRIx8 "", state->AppBarState);
675
0
  if (order->fieldFlags & WINDOW_ORDER_FIELD_APPBAR_EDGE)
676
0
  {
677
0
    const char* appBarEdgeStr = NULL;
678
0
    switch (state->AppBarEdge)
679
0
    {
680
0
      case 0:
681
0
        appBarEdgeStr = "left";
682
0
        break;
683
0
      case 1:
684
0
        appBarEdgeStr = "top";
685
0
        break;
686
0
      case 2:
687
0
        appBarEdgeStr = "right";
688
0
        break;
689
0
      case 3:
690
0
        appBarEdgeStr = "bottom";
691
0
        break;
692
0
      default:
693
0
        appBarEdgeStr = "<unknown>";
694
0
        break;
695
0
    }
696
0
    DUMP_APPEND(buffer, bufferSize, " appBarEdge=%s", appBarEdgeStr);
697
0
  }
698
699
0
  WLog_Print(log, WLOG_DEBUG, buffer);
700
0
}
701
702
static BOOL update_recv_window_info_order(rdpUpdate* update, wStream* s,
703
                                          WINDOW_ORDER_INFO* orderInfo)
704
0
{
705
0
  rdp_update_internal* up = update_cast(update);
706
0
  rdpContext* context = update->context;
707
0
  rdpWindowUpdate* window = update->window;
708
709
0
  BOOL result = TRUE;
710
711
0
  WINPR_ASSERT(s);
712
0
  WINPR_ASSERT(context);
713
0
  WINPR_ASSERT(window);
714
0
  WINPR_ASSERT(orderInfo);
715
716
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
717
0
    return FALSE;
718
719
0
  Stream_Read_UINT32(s, orderInfo->windowId); /* windowId (4 bytes) */
720
721
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
722
0
  {
723
0
    WINDOW_ICON_ORDER window_icon = { 0 };
724
0
    result = update_read_window_icon_order(s, orderInfo, &window_icon);
725
726
0
    if (result)
727
0
    {
728
0
      WLog_Print(up->log, WLOG_DEBUG, "WindowIcon windowId=0x%" PRIx32 "",
729
0
                 orderInfo->windowId);
730
0
      IFCALLRET(window->WindowIcon, result, context, orderInfo, &window_icon);
731
0
    }
732
733
0
    update_free_window_icon_info(window_icon.iconInfo);
734
0
    free(window_icon.iconInfo);
735
0
  }
736
0
  else if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
737
0
  {
738
0
    WINDOW_CACHED_ICON_ORDER window_cached_icon = { 0 };
739
0
    result = update_read_window_cached_icon_order(s, orderInfo, &window_cached_icon);
740
741
0
    if (result)
742
0
    {
743
0
      WLog_Print(up->log, WLOG_DEBUG, "WindowCachedIcon windowId=0x%" PRIx32 "",
744
0
                 orderInfo->windowId);
745
0
      IFCALLRET(window->WindowCachedIcon, result, context, orderInfo, &window_cached_icon);
746
0
    }
747
0
  }
748
0
  else if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
749
0
  {
750
0
    update_read_window_delete_order(s, orderInfo);
751
0
    WLog_Print(up->log, WLOG_DEBUG, "WindowDelete windowId=0x%" PRIx32 "", orderInfo->windowId);
752
0
    IFCALLRET(window->WindowDelete, result, context, orderInfo);
753
0
  }
754
0
  else
755
0
  {
756
0
    WINDOW_STATE_ORDER windowState = { 0 };
757
0
    result = update_read_window_state_order(s, orderInfo, &windowState);
758
759
0
    if (result)
760
0
    {
761
0
      if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
762
0
      {
763
0
        dump_window_state_order(up->log, "WindowCreate", orderInfo, &windowState);
764
0
        IFCALLRET(window->WindowCreate, result, context, orderInfo, &windowState);
765
0
      }
766
0
      else
767
0
      {
768
0
        dump_window_state_order(up->log, "WindowUpdate", orderInfo, &windowState);
769
0
        IFCALLRET(window->WindowUpdate, result, context, orderInfo, &windowState);
770
0
      }
771
772
0
      update_free_window_state(&windowState);
773
0
    }
774
0
  }
775
776
0
  return result;
777
0
}
778
779
static void update_notify_icon_state_order_free(NOTIFY_ICON_STATE_ORDER* notify)
780
0
{
781
0
  free(notify->toolTip.string);
782
0
  free(notify->infoTip.text.string);
783
0
  free(notify->infoTip.title.string);
784
0
  update_free_window_icon_info(&notify->icon);
785
0
  memset(notify, 0, sizeof(NOTIFY_ICON_STATE_ORDER));
786
0
}
787
788
static BOOL update_read_notification_icon_state_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
789
                                                      NOTIFY_ICON_STATE_ORDER* notify_icon_state)
790
0
{
791
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_VERSION)
792
0
  {
793
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
794
0
      return FALSE;
795
796
0
    Stream_Read_UINT32(s, notify_icon_state->version); /* version (4 bytes) */
797
0
  }
798
799
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
800
0
  {
801
0
    if (!rail_read_unicode_string(s,
802
0
                                  &notify_icon_state->toolTip)) /* toolTip (UNICODE_STRING) */
803
0
      return FALSE;
804
0
  }
805
806
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
807
0
  {
808
0
    if (!update_read_notify_icon_infotip(
809
0
            s, &notify_icon_state->infoTip)) /* infoTip (NOTIFY_ICON_INFOTIP) */
810
0
      return FALSE;
811
0
  }
812
813
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_STATE)
814
0
  {
815
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
816
0
      return FALSE;
817
818
0
    Stream_Read_UINT32(s, notify_icon_state->state); /* state (4 bytes) */
819
0
  }
820
821
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_ICON)
822
0
  {
823
0
    if (!update_read_icon_info(s, &notify_icon_state->icon)) /* icon (ICON_INFO) */
824
0
      return FALSE;
825
0
  }
826
827
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_CACHED_ICON)
828
0
  {
829
0
    if (!update_read_cached_icon_info(
830
0
            s, &notify_icon_state->cachedIcon)) /* cachedIcon (CACHED_ICON_INFO) */
831
0
      return FALSE;
832
0
  }
833
834
0
  return TRUE;
835
0
}
836
837
static void update_read_notification_icon_delete_order(wStream* s, WINDOW_ORDER_INFO* orderInfo)
838
0
{
839
  /* notification icon deletion event */
840
0
}
841
842
static BOOL update_recv_notification_icon_info_order(rdpUpdate* update, wStream* s,
843
                                                     WINDOW_ORDER_INFO* orderInfo)
844
0
{
845
0
  rdp_update_internal* up = update_cast(update);
846
0
  rdpContext* context = update->context;
847
0
  rdpWindowUpdate* window = update->window;
848
0
  BOOL result = TRUE;
849
850
0
  WINPR_ASSERT(s);
851
0
  WINPR_ASSERT(orderInfo);
852
0
  WINPR_ASSERT(context);
853
0
  WINPR_ASSERT(window);
854
855
0
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
856
0
    return FALSE;
857
858
0
  Stream_Read_UINT32(s, orderInfo->windowId);     /* windowId (4 bytes) */
859
0
  Stream_Read_UINT32(s, orderInfo->notifyIconId); /* notifyIconId (4 bytes) */
860
861
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_DELETED)
862
0
  {
863
0
    update_read_notification_icon_delete_order(s, orderInfo);
864
0
    WLog_Print(up->log, WLOG_DEBUG, "NotifyIconDelete");
865
0
    IFCALLRET(window->NotifyIconDelete, result, context, orderInfo);
866
0
  }
867
0
  else
868
0
  {
869
0
    NOTIFY_ICON_STATE_ORDER notify_icon_state = { 0 };
870
0
    result = update_read_notification_icon_state_order(s, orderInfo, &notify_icon_state);
871
872
0
    if (!result)
873
0
      goto fail;
874
875
0
    if (orderInfo->fieldFlags & WINDOW_ORDER_STATE_NEW)
876
0
    {
877
0
      WLog_Print(up->log, WLOG_DEBUG, "NotifyIconCreate");
878
0
      IFCALLRET(window->NotifyIconCreate, result, context, orderInfo, &notify_icon_state);
879
0
    }
880
0
    else
881
0
    {
882
0
      WLog_Print(up->log, WLOG_DEBUG, "NotifyIconUpdate");
883
0
      IFCALLRET(window->NotifyIconUpdate, result, context, orderInfo, &notify_icon_state);
884
0
    }
885
0
  fail:
886
0
    update_notify_icon_state_order_free(&notify_icon_state);
887
0
  }
888
889
0
  return result;
890
0
}
891
892
static BOOL update_read_desktop_actively_monitored_order(wStream* s, WINDOW_ORDER_INFO* orderInfo,
893
                                                         MONITORED_DESKTOP_ORDER* monitored_desktop)
894
0
{
895
0
  int size = 0;
896
897
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
898
0
  {
899
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
900
0
      return FALSE;
901
902
0
    Stream_Read_UINT32(s, monitored_desktop->activeWindowId); /* activeWindowId (4 bytes) */
903
0
  }
904
905
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
906
0
  {
907
0
    UINT32* newid = NULL;
908
909
0
    if (!Stream_CheckAndLogRequiredLength(TAG, s, 1))
910
0
      return FALSE;
911
912
0
    Stream_Read_UINT8(s, monitored_desktop->numWindowIds); /* numWindowIds (1 byte) */
913
914
0
    if (!Stream_CheckAndLogRequiredLengthOfSize(TAG, s, monitored_desktop->numWindowIds, 4ull))
915
0
      return FALSE;
916
917
0
    if (monitored_desktop->numWindowIds > 0)
918
0
    {
919
0
      size = sizeof(UINT32) * monitored_desktop->numWindowIds;
920
0
      newid = (UINT32*)realloc(monitored_desktop->windowIds, size);
921
922
0
      if (!newid)
923
0
      {
924
0
        free(monitored_desktop->windowIds);
925
0
        monitored_desktop->windowIds = NULL;
926
0
        return FALSE;
927
0
      }
928
929
0
      monitored_desktop->windowIds = newid;
930
931
      /* windowIds */
932
0
      for (UINT32 i = 0; i < (int)monitored_desktop->numWindowIds; i++)
933
0
      {
934
0
        Stream_Read_UINT32(s, monitored_desktop->windowIds[i]);
935
0
      }
936
0
    }
937
0
  }
938
939
0
  return TRUE;
940
0
}
941
942
static void update_read_desktop_non_monitored_order(wStream* s, WINDOW_ORDER_INFO* orderInfo)
943
0
{
944
  /* non-monitored desktop notification event */
945
0
}
946
947
static void dump_monitored_desktop(wLog* log, const char* msg, const WINDOW_ORDER_INFO* orderInfo,
948
                                   const MONITORED_DESKTOP_ORDER* monitored)
949
0
{
950
0
  char buffer[1000] = { 0 };
951
0
  const size_t bufferSize = sizeof(buffer) - 1;
952
953
0
  DUMP_APPEND(buffer, bufferSize, "%s", msg);
954
955
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND)
956
0
    DUMP_APPEND(buffer, bufferSize, " activeWindowId=0x%" PRIx32 "", monitored->activeWindowId);
957
958
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
959
0
  {
960
0
    DUMP_APPEND(buffer, bufferSize, " windows=(");
961
0
    for (UINT32 i = 0; i < monitored->numWindowIds; i++)
962
0
    {
963
0
      DUMP_APPEND(buffer, bufferSize, "0x%" PRIx32 ",", monitored->windowIds[i]);
964
0
    }
965
0
    DUMP_APPEND(buffer, bufferSize, ")");
966
0
  }
967
0
  WLog_Print(log, WLOG_DEBUG, buffer);
968
0
}
969
970
static BOOL update_recv_desktop_info_order(rdpUpdate* update, wStream* s,
971
                                           WINDOW_ORDER_INFO* orderInfo)
972
0
{
973
0
  rdp_update_internal* up = update_cast(update);
974
0
  rdpContext* context = update->context;
975
0
  rdpWindowUpdate* window = update->window;
976
0
  BOOL result = TRUE;
977
978
0
  WINPR_ASSERT(s);
979
0
  WINPR_ASSERT(orderInfo);
980
0
  WINPR_ASSERT(context);
981
0
  WINPR_ASSERT(window);
982
983
0
  if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_NONE)
984
0
  {
985
0
    update_read_desktop_non_monitored_order(s, orderInfo);
986
0
    WLog_Print(up->log, WLOG_DEBUG, "NonMonitoredDesktop, windowId=0x%" PRIx32 "",
987
0
               orderInfo->windowId);
988
0
    IFCALLRET(window->NonMonitoredDesktop, result, context, orderInfo);
989
0
  }
990
0
  else
991
0
  {
992
0
    MONITORED_DESKTOP_ORDER monitored_desktop = { 0 };
993
0
    result = update_read_desktop_actively_monitored_order(s, orderInfo, &monitored_desktop);
994
995
0
    if (result)
996
0
    {
997
0
      dump_monitored_desktop(up->log, "ActivelyMonitoredDesktop", orderInfo,
998
0
                             &monitored_desktop);
999
0
      IFCALLRET(window->MonitoredDesktop, result, context, orderInfo, &monitored_desktop);
1000
0
    }
1001
1002
0
    free(monitored_desktop.windowIds);
1003
0
  }
1004
1005
0
  return result;
1006
0
}
1007
1008
void update_free_window_icon_info(ICON_INFO* iconInfo)
1009
0
{
1010
0
  if (!iconInfo)
1011
0
    return;
1012
1013
0
  free(iconInfo->bitsColor);
1014
0
  iconInfo->bitsColor = NULL;
1015
0
  free(iconInfo->bitsMask);
1016
0
  iconInfo->bitsMask = NULL;
1017
0
  free(iconInfo->colorTable);
1018
0
  iconInfo->colorTable = NULL;
1019
0
}
1020
1021
BOOL update_recv_altsec_window_order(rdpUpdate* update, wStream* s)
1022
15.0k
{
1023
15.0k
  BOOL rc = TRUE;
1024
15.0k
  size_t remaining = 0;
1025
15.0k
  UINT16 orderSize = 0;
1026
15.0k
  WINDOW_ORDER_INFO orderInfo = { 0 };
1027
15.0k
  rdp_update_internal* up = update_cast(update);
1028
1029
15.0k
  remaining = Stream_GetRemainingLength(s);
1030
1031
15.0k
  if (!Stream_CheckAndLogRequiredLength(TAG, s, 6))
1032
3.89k
    return FALSE;
1033
1034
11.1k
  Stream_Read_UINT16(s, orderSize);            /* orderSize (2 bytes) */
1035
11.1k
  Stream_Read_UINT32(s, orderInfo.fieldFlags); /* FieldsPresentFlags (4 bytes) */
1036
1037
11.1k
  if (remaining + 1 < orderSize)
1038
4.91k
  {
1039
4.91k
    WLog_Print(up->log, WLOG_ERROR, "Stream short orderSize");
1040
4.91k
    return FALSE;
1041
4.91k
  }
1042
1043
6.20k
  if (!window_order_supported(update->context->settings, orderInfo.fieldFlags))
1044
6.20k
  {
1045
6.20k
    WLog_INFO(TAG, "Window order %08" PRIx32 " not supported!", orderInfo.fieldFlags);
1046
6.20k
    return FALSE;
1047
6.20k
  }
1048
1049
0
  if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_WINDOW)
1050
0
    rc = update_recv_window_info_order(update, s, &orderInfo);
1051
0
  else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_NOTIFY)
1052
0
    rc = update_recv_notification_icon_info_order(update, s, &orderInfo);
1053
0
  else if (orderInfo.fieldFlags & WINDOW_ORDER_TYPE_DESKTOP)
1054
0
    rc = update_recv_desktop_info_order(update, s, &orderInfo);
1055
1056
0
  if (!rc)
1057
0
    WLog_Print(up->log, WLOG_ERROR, "windoworder flags %08" PRIx32 " failed",
1058
0
               orderInfo.fieldFlags);
1059
1060
0
  return rc;
1061
6.20k
}