Coverage Report

Created: 2026-10-15 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/FreeRDP/libfreerdp/core/message.c
Line
Count
Source
1
/**
2
 * FreeRDP: A Remote Desktop Protocol Implementation
3
 * Asynchronous Message Queue
4
 *
5
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6
 * Copyright 2017 Armin Novak <armin.novak@thincast.com>
7
 * Copyright 2017 Thincast Technologies GmbH
8
 *
9
 * Licensed under the Apache License, Version 2.0 (the "License");
10
 * you may not use this file except in compliance with the License.
11
 * You may obtain a copy of the License at
12
 *
13
 *     http://www.apache.org/licenses/LICENSE-2.0
14
 *
15
 * Unless required by applicable law or agreed to in writing, software
16
 * distributed under the License is distributed on an "AS IS" BASIS,
17
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
 * See the License for the specific language governing permissions and
19
 * limitations under the License.
20
 */
21
22
#include <freerdp/config.h>
23
24
#include <winpr/assert.h>
25
26
#include "rdp.h"
27
#include "message.h"
28
#include "transport.h"
29
30
#include <freerdp/log.h>
31
#include <freerdp/freerdp.h>
32
33
#include <winpr/crt.h>
34
#include <winpr/stream.h>
35
#include <winpr/collections.h>
36
37
#include "../cache/pointer.h"
38
#include "../cache/bitmap.h"
39
#include "../cache/palette.h"
40
#include "../cache/glyph.h"
41
#include "../cache/brush.h"
42
#include "../cache/cache.h"
43
44
#define TAG FREERDP_TAG("core.message")
45
46
/* Update */
47
48
static BOOL update_message_BeginPaint(rdpContext* context)
49
0
{
50
0
  rdp_update_internal* up = nullptr;
51
52
0
  if (!context || !context->update)
53
0
    return FALSE;
54
55
0
  up = update_cast(context->update);
56
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, BeginPaint), nullptr,
57
0
                           nullptr);
58
0
}
59
60
static BOOL update_message_EndPaint(rdpContext* context)
61
0
{
62
0
  rdp_update_internal* up = nullptr;
63
64
0
  if (!context || !context->update)
65
0
    return FALSE;
66
67
0
  up = update_cast(context->update);
68
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, EndPaint), nullptr,
69
0
                           nullptr);
70
0
}
71
72
static BOOL update_message_SetBounds(rdpContext* context, const rdpBounds* bounds)
73
0
{
74
0
  rdpBounds* wParam = nullptr;
75
0
  rdp_update_internal* up = nullptr;
76
77
0
  if (!context || !context->update)
78
0
    return FALSE;
79
80
0
  if (bounds)
81
0
  {
82
0
    wParam = (rdpBounds*)malloc(sizeof(rdpBounds));
83
84
0
    if (!wParam)
85
0
      return FALSE;
86
87
0
    CopyMemory(wParam, bounds, sizeof(rdpBounds));
88
0
  }
89
90
0
  up = update_cast(context->update);
91
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, SetBounds),
92
0
                           (void*)wParam, nullptr);
93
0
}
94
95
static BOOL update_message_Synchronize(rdpContext* context)
96
0
{
97
0
  rdp_update_internal* up = nullptr;
98
99
0
  if (!context || !context->update)
100
0
    return FALSE;
101
102
0
  up = update_cast(context->update);
103
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, Synchronize), nullptr,
104
0
                           nullptr);
105
0
}
106
107
static BOOL update_message_DesktopResize(rdpContext* context)
108
0
{
109
0
  rdp_update_internal* up = nullptr;
110
111
0
  if (!context || !context->update)
112
0
    return FALSE;
113
114
0
  up = update_cast(context->update);
115
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, DesktopResize),
116
0
                           nullptr, nullptr);
117
0
}
118
119
static BOOL update_message_BitmapUpdate(rdpContext* context, const BITMAP_UPDATE* bitmap)
120
0
{
121
0
  BITMAP_UPDATE* wParam = nullptr;
122
0
  rdp_update_internal* up = nullptr;
123
124
0
  if (!context || !context->update || !bitmap)
125
0
    return FALSE;
126
127
0
  wParam = copy_bitmap_update(context, bitmap);
128
129
0
  if (!wParam)
130
0
    return FALSE;
131
132
0
  up = update_cast(context->update);
133
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, BitmapUpdate),
134
0
                           (void*)wParam, nullptr);
135
0
}
136
137
static BOOL update_message_Palette(rdpContext* context, const PALETTE_UPDATE* palette)
138
0
{
139
0
  PALETTE_UPDATE* wParam = nullptr;
140
0
  rdp_update_internal* up = nullptr;
141
142
0
  if (!context || !context->update || !palette)
143
0
    return FALSE;
144
145
0
  wParam = copy_palette_update(context, palette);
146
147
0
  if (!wParam)
148
0
    return FALSE;
149
150
0
  up = update_cast(context->update);
151
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, Palette),
152
0
                           (void*)wParam, nullptr);
153
0
}
154
155
static BOOL update_message_PlaySound(rdpContext* context, const PLAY_SOUND_UPDATE* playSound)
156
0
{
157
0
  PLAY_SOUND_UPDATE* wParam = nullptr;
158
0
  rdp_update_internal* up = nullptr;
159
160
0
  if (!context || !context->update || !playSound)
161
0
    return FALSE;
162
163
0
  wParam = (PLAY_SOUND_UPDATE*)malloc(sizeof(PLAY_SOUND_UPDATE));
164
165
0
  if (!wParam)
166
0
    return FALSE;
167
168
0
  CopyMemory(wParam, playSound, sizeof(PLAY_SOUND_UPDATE));
169
170
0
  up = update_cast(context->update);
171
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, PlaySound),
172
0
                           (void*)wParam, nullptr);
173
0
}
174
175
static BOOL update_message_SetKeyboardIndicators(rdpContext* context, UINT16 led_flags)
176
0
{
177
0
  rdp_update_internal* up = nullptr;
178
179
0
  if (!context || !context->update)
180
0
    return FALSE;
181
182
0
  up = update_cast(context->update);
183
0
  return MessageQueue_Post(up->queue, (void*)context,
184
0
                           MakeMessageId(Update, SetKeyboardIndicators), (void*)(size_t)led_flags,
185
0
                           nullptr);
186
0
}
187
188
static BOOL update_message_SetKeyboardImeStatus(rdpContext* context, UINT16 imeId, UINT32 imeState,
189
                                                UINT32 imeConvMode)
190
0
{
191
0
  rdp_update_internal* up = nullptr;
192
193
0
  if (!context || !context->update)
194
0
    return FALSE;
195
196
0
  up = update_cast(context->update);
197
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, SetKeyboardImeStatus),
198
0
                           (void*)(size_t)((((UINT32)imeId << 16UL) & 0xFFFF0000) | imeState),
199
0
                           (void*)(size_t)imeConvMode);
200
0
}
201
202
static BOOL update_message_RefreshRect(rdpContext* context, BYTE count, const RECTANGLE_16* areas)
203
0
{
204
0
  RECTANGLE_16* lParam = nullptr;
205
0
  rdp_update_internal* up = nullptr;
206
207
0
  if (!context || !context->update || !areas)
208
0
    return FALSE;
209
210
0
  lParam = (RECTANGLE_16*)calloc(count, sizeof(RECTANGLE_16));
211
212
0
  if (!lParam)
213
0
    return FALSE;
214
215
0
  CopyMemory(lParam, areas, sizeof(RECTANGLE_16) * count);
216
217
0
  up = update_cast(context->update);
218
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, RefreshRect),
219
0
                           (void*)(size_t)count, (void*)lParam);
220
0
}
221
222
static BOOL update_message_SuppressOutput(rdpContext* context, BYTE allow, const RECTANGLE_16* area)
223
0
{
224
0
  RECTANGLE_16* lParam = nullptr;
225
0
  rdp_update_internal* up = nullptr;
226
227
0
  if (!context || !context->update)
228
0
    return FALSE;
229
230
0
  if (area)
231
0
  {
232
0
    lParam = (RECTANGLE_16*)malloc(sizeof(RECTANGLE_16));
233
234
0
    if (!lParam)
235
0
      return FALSE;
236
237
0
    CopyMemory(lParam, area, sizeof(RECTANGLE_16));
238
0
  }
239
240
0
  up = update_cast(context->update);
241
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, SuppressOutput),
242
0
                           (void*)(size_t)allow, (void*)lParam);
243
0
}
244
245
static BOOL update_message_SurfaceCommand(rdpContext* context, wStream* s)
246
0
{
247
0
  wStream* wParam = nullptr;
248
0
  rdp_update_internal* up = nullptr;
249
250
0
  if (!context || !context->update || !s)
251
0
    return FALSE;
252
253
0
  wParam = Stream_New(nullptr, Stream_GetRemainingLength(s));
254
255
0
  if (!wParam)
256
0
    return FALSE;
257
258
0
  Stream_Copy(s, wParam, Stream_GetRemainingLength(s));
259
0
  Stream_ResetPosition(wParam);
260
261
0
  up = update_cast(context->update);
262
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, SurfaceCommand),
263
0
                           (void*)wParam, nullptr);
264
0
}
265
266
static BOOL update_message_SurfaceBits(rdpContext* context,
267
                                       const SURFACE_BITS_COMMAND* surfaceBitsCommand)
268
0
{
269
0
  SURFACE_BITS_COMMAND* wParam = nullptr;
270
0
  rdp_update_internal* up = nullptr;
271
272
0
  if (!context || !context->update || !surfaceBitsCommand)
273
0
    return FALSE;
274
275
0
  wParam = copy_surface_bits_command(context, surfaceBitsCommand);
276
277
0
  if (!wParam)
278
0
    return FALSE;
279
280
0
  up = update_cast(context->update);
281
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, SurfaceBits),
282
0
                           (void*)wParam, nullptr);
283
0
}
284
285
static BOOL update_message_SurfaceFrameMarker(rdpContext* context,
286
                                              const SURFACE_FRAME_MARKER* surfaceFrameMarker)
287
0
{
288
0
  SURFACE_FRAME_MARKER* wParam = nullptr;
289
0
  rdp_update_internal* up = nullptr;
290
291
0
  if (!context || !context->update || !surfaceFrameMarker)
292
0
    return FALSE;
293
294
0
  wParam = (SURFACE_FRAME_MARKER*)malloc(sizeof(SURFACE_FRAME_MARKER));
295
296
0
  if (!wParam)
297
0
    return FALSE;
298
299
0
  CopyMemory(wParam, surfaceFrameMarker, sizeof(SURFACE_FRAME_MARKER));
300
301
0
  up = update_cast(context->update);
302
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(Update, SurfaceFrameMarker),
303
0
                           (void*)wParam, nullptr);
304
0
}
305
306
static BOOL update_message_SurfaceFrameAcknowledge(rdpContext* context, UINT32 frameId)
307
0
{
308
0
  rdp_update_internal* up = nullptr;
309
310
0
  if (!context || !context->update)
311
0
    return FALSE;
312
313
0
  up = update_cast(context->update);
314
0
  return MessageQueue_Post(up->queue, (void*)context,
315
0
                           MakeMessageId(Update, SurfaceFrameAcknowledge), (void*)(size_t)frameId,
316
0
                           nullptr);
317
0
}
318
319
/* Primary Update */
320
321
static BOOL update_message_DstBlt(rdpContext* context, const DSTBLT_ORDER* dstBlt)
322
0
{
323
0
  DSTBLT_ORDER* wParam = nullptr;
324
0
  rdp_update_internal* up = nullptr;
325
326
0
  if (!context || !context->update || !dstBlt)
327
0
    return FALSE;
328
329
0
  wParam = (DSTBLT_ORDER*)malloc(sizeof(DSTBLT_ORDER));
330
331
0
  if (!wParam)
332
0
    return FALSE;
333
334
0
  CopyMemory(wParam, dstBlt, sizeof(DSTBLT_ORDER));
335
336
0
  up = update_cast(context->update);
337
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, DstBlt),
338
0
                           (void*)wParam, nullptr);
339
0
}
340
341
static BOOL update_message_PatBlt(rdpContext* context, PATBLT_ORDER* patBlt)
342
0
{
343
0
  PATBLT_ORDER* wParam = nullptr;
344
0
  rdp_update_internal* up = nullptr;
345
346
0
  if (!context || !context->update || !patBlt)
347
0
    return FALSE;
348
349
0
  wParam = (PATBLT_ORDER*)malloc(sizeof(PATBLT_ORDER));
350
351
0
  if (!wParam)
352
0
    return FALSE;
353
354
0
  CopyMemory(wParam, patBlt, sizeof(PATBLT_ORDER));
355
0
  wParam->brush.data = (BYTE*)wParam->brush.p8x8;
356
357
0
  up = update_cast(context->update);
358
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, PatBlt),
359
0
                           (void*)wParam, nullptr);
360
0
}
361
362
static BOOL update_message_ScrBlt(rdpContext* context, const SCRBLT_ORDER* scrBlt)
363
0
{
364
0
  SCRBLT_ORDER* wParam = nullptr;
365
0
  rdp_update_internal* up = nullptr;
366
367
0
  if (!context || !context->update || !scrBlt)
368
0
    return FALSE;
369
370
0
  wParam = (SCRBLT_ORDER*)malloc(sizeof(SCRBLT_ORDER));
371
372
0
  if (!wParam)
373
0
    return FALSE;
374
375
0
  CopyMemory(wParam, scrBlt, sizeof(SCRBLT_ORDER));
376
377
0
  up = update_cast(context->update);
378
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, ScrBlt),
379
0
                           (void*)wParam, nullptr);
380
0
}
381
382
static BOOL update_message_OpaqueRect(rdpContext* context, const OPAQUE_RECT_ORDER* opaqueRect)
383
0
{
384
0
  OPAQUE_RECT_ORDER* wParam = nullptr;
385
0
  rdp_update_internal* up = nullptr;
386
387
0
  if (!context || !context->update || !opaqueRect)
388
0
    return FALSE;
389
390
0
  wParam = (OPAQUE_RECT_ORDER*)malloc(sizeof(OPAQUE_RECT_ORDER));
391
392
0
  if (!wParam)
393
0
    return FALSE;
394
395
0
  CopyMemory(wParam, opaqueRect, sizeof(OPAQUE_RECT_ORDER));
396
397
0
  up = update_cast(context->update);
398
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, OpaqueRect),
399
0
                           (void*)wParam, nullptr);
400
0
}
401
402
static BOOL update_message_DrawNineGrid(rdpContext* context,
403
                                        const DRAW_NINE_GRID_ORDER* drawNineGrid)
404
0
{
405
0
  DRAW_NINE_GRID_ORDER* wParam = nullptr;
406
0
  rdp_update_internal* up = nullptr;
407
408
0
  if (!context || !context->update || !drawNineGrid)
409
0
    return FALSE;
410
411
0
  wParam = (DRAW_NINE_GRID_ORDER*)malloc(sizeof(DRAW_NINE_GRID_ORDER));
412
413
0
  if (!wParam)
414
0
    return FALSE;
415
416
0
  CopyMemory(wParam, drawNineGrid, sizeof(DRAW_NINE_GRID_ORDER));
417
418
0
  up = update_cast(context->update);
419
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, DrawNineGrid),
420
0
                           (void*)wParam, nullptr);
421
0
}
422
423
static BOOL update_message_MultiDstBlt(rdpContext* context, const MULTI_DSTBLT_ORDER* multiDstBlt)
424
0
{
425
0
  MULTI_DSTBLT_ORDER* wParam = nullptr;
426
0
  rdp_update_internal* up = nullptr;
427
428
0
  if (!context || !context->update || !multiDstBlt)
429
0
    return FALSE;
430
431
0
  wParam = (MULTI_DSTBLT_ORDER*)malloc(sizeof(MULTI_DSTBLT_ORDER));
432
433
0
  if (!wParam)
434
0
    return FALSE;
435
436
0
  CopyMemory(wParam, multiDstBlt, sizeof(MULTI_DSTBLT_ORDER));
437
438
0
  up = update_cast(context->update);
439
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, MultiDstBlt),
440
0
                           (void*)wParam, nullptr);
441
0
}
442
443
static BOOL update_message_MultiPatBlt(rdpContext* context, const MULTI_PATBLT_ORDER* multiPatBlt)
444
0
{
445
0
  MULTI_PATBLT_ORDER* wParam = nullptr;
446
0
  rdp_update_internal* up = nullptr;
447
448
0
  if (!context || !context->update || !multiPatBlt)
449
0
    return FALSE;
450
451
0
  wParam = (MULTI_PATBLT_ORDER*)malloc(sizeof(MULTI_PATBLT_ORDER));
452
453
0
  if (!wParam)
454
0
    return FALSE;
455
456
0
  CopyMemory(wParam, multiPatBlt, sizeof(MULTI_PATBLT_ORDER));
457
0
  wParam->brush.data = (BYTE*)wParam->brush.p8x8;
458
459
0
  up = update_cast(context->update);
460
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, MultiPatBlt),
461
0
                           (void*)wParam, nullptr);
462
0
}
463
464
static BOOL update_message_MultiScrBlt(rdpContext* context, const MULTI_SCRBLT_ORDER* multiScrBlt)
465
0
{
466
0
  MULTI_SCRBLT_ORDER* wParam = nullptr;
467
0
  rdp_update_internal* up = nullptr;
468
469
0
  if (!context || !context->update || !multiScrBlt)
470
0
    return FALSE;
471
472
0
  wParam = (MULTI_SCRBLT_ORDER*)malloc(sizeof(MULTI_SCRBLT_ORDER));
473
474
0
  if (!wParam)
475
0
    return FALSE;
476
477
0
  CopyMemory(wParam, multiScrBlt, sizeof(MULTI_SCRBLT_ORDER));
478
479
0
  up = update_cast(context->update);
480
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, MultiScrBlt),
481
0
                           (void*)wParam, nullptr);
482
0
}
483
484
static BOOL update_message_MultiOpaqueRect(rdpContext* context,
485
                                           const MULTI_OPAQUE_RECT_ORDER* multiOpaqueRect)
486
0
{
487
0
  MULTI_OPAQUE_RECT_ORDER* wParam = nullptr;
488
0
  rdp_update_internal* up = nullptr;
489
490
0
  if (!context || !context->update || !multiOpaqueRect)
491
0
    return FALSE;
492
493
0
  wParam = (MULTI_OPAQUE_RECT_ORDER*)malloc(sizeof(MULTI_OPAQUE_RECT_ORDER));
494
495
0
  if (!wParam)
496
0
    return FALSE;
497
498
0
  CopyMemory(wParam, multiOpaqueRect, sizeof(MULTI_OPAQUE_RECT_ORDER));
499
500
0
  up = update_cast(context->update);
501
0
  return MessageQueue_Post(up->queue, (void*)context,
502
0
                           MakeMessageId(PrimaryUpdate, MultiOpaqueRect), (void*)wParam, nullptr);
503
0
}
504
505
static BOOL update_message_MultiDrawNineGrid(rdpContext* context,
506
                                             const MULTI_DRAW_NINE_GRID_ORDER* multiDrawNineGrid)
507
0
{
508
0
  MULTI_DRAW_NINE_GRID_ORDER* wParam = nullptr;
509
0
  rdp_update_internal* up = nullptr;
510
511
0
  if (!context || !context->update || !multiDrawNineGrid)
512
0
    return FALSE;
513
514
0
  wParam = (MULTI_DRAW_NINE_GRID_ORDER*)malloc(sizeof(MULTI_DRAW_NINE_GRID_ORDER));
515
516
0
  if (!wParam)
517
0
    return FALSE;
518
519
0
  CopyMemory(wParam, multiDrawNineGrid, sizeof(MULTI_DRAW_NINE_GRID_ORDER));
520
  /* TODO: complete copy */
521
522
0
  up = update_cast(context->update);
523
0
  return MessageQueue_Post(up->queue, (void*)context,
524
0
                           MakeMessageId(PrimaryUpdate, MultiDrawNineGrid), (void*)wParam,
525
0
                           nullptr);
526
0
}
527
528
static BOOL update_message_LineTo(rdpContext* context, const LINE_TO_ORDER* lineTo)
529
0
{
530
0
  LINE_TO_ORDER* wParam = nullptr;
531
0
  rdp_update_internal* up = nullptr;
532
533
0
  if (!context || !context->update || !lineTo)
534
0
    return FALSE;
535
536
0
  wParam = (LINE_TO_ORDER*)malloc(sizeof(LINE_TO_ORDER));
537
538
0
  if (!wParam)
539
0
    return FALSE;
540
541
0
  CopyMemory(wParam, lineTo, sizeof(LINE_TO_ORDER));
542
543
0
  up = update_cast(context->update);
544
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, LineTo),
545
0
                           (void*)wParam, nullptr);
546
0
}
547
548
static BOOL update_message_Polyline(rdpContext* context, const POLYLINE_ORDER* polyline)
549
0
{
550
0
  POLYLINE_ORDER* wParam = nullptr;
551
0
  rdp_update_internal* up = nullptr;
552
553
0
  if (!context || !context->update || !polyline)
554
0
    return FALSE;
555
556
0
  wParam = (POLYLINE_ORDER*)malloc(sizeof(POLYLINE_ORDER));
557
558
0
  if (!wParam)
559
0
    return FALSE;
560
561
0
  CopyMemory(wParam, polyline, sizeof(POLYLINE_ORDER));
562
0
  wParam->points = (DELTA_POINT*)calloc(wParam->numDeltaEntries, sizeof(DELTA_POINT));
563
564
0
  if (!wParam->points)
565
0
  {
566
0
    free(wParam);
567
0
    return FALSE;
568
0
  }
569
570
0
  CopyMemory(wParam->points, polyline->points, sizeof(DELTA_POINT) * wParam->numDeltaEntries);
571
572
0
  up = update_cast(context->update);
573
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, Polyline),
574
0
                           (void*)wParam, nullptr);
575
0
}
576
577
static BOOL update_message_MemBlt(rdpContext* context, MEMBLT_ORDER* memBlt)
578
0
{
579
0
  MEMBLT_ORDER* wParam = nullptr;
580
0
  rdp_update_internal* up = nullptr;
581
582
0
  if (!context || !context->update || !memBlt)
583
0
    return FALSE;
584
585
0
  wParam = (MEMBLT_ORDER*)malloc(sizeof(MEMBLT_ORDER));
586
587
0
  if (!wParam)
588
0
    return FALSE;
589
590
0
  CopyMemory(wParam, memBlt, sizeof(MEMBLT_ORDER));
591
592
0
  up = update_cast(context->update);
593
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, MemBlt),
594
0
                           (void*)wParam, nullptr);
595
0
}
596
597
static BOOL update_message_Mem3Blt(rdpContext* context, MEM3BLT_ORDER* mem3Blt)
598
0
{
599
0
  MEM3BLT_ORDER* wParam = nullptr;
600
0
  rdp_update_internal* up = nullptr;
601
602
0
  if (!context || !context->update || !mem3Blt)
603
0
    return FALSE;
604
605
0
  wParam = (MEM3BLT_ORDER*)malloc(sizeof(MEM3BLT_ORDER));
606
607
0
  if (!wParam)
608
0
    return FALSE;
609
610
0
  CopyMemory(wParam, mem3Blt, sizeof(MEM3BLT_ORDER));
611
0
  wParam->brush.data = (BYTE*)wParam->brush.p8x8;
612
613
0
  up = update_cast(context->update);
614
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, Mem3Blt),
615
0
                           (void*)wParam, nullptr);
616
0
}
617
618
static BOOL update_message_SaveBitmap(rdpContext* context, const SAVE_BITMAP_ORDER* saveBitmap)
619
0
{
620
0
  SAVE_BITMAP_ORDER* wParam = nullptr;
621
0
  rdp_update_internal* up = nullptr;
622
623
0
  if (!context || !context->update || !saveBitmap)
624
0
    return FALSE;
625
626
0
  wParam = (SAVE_BITMAP_ORDER*)malloc(sizeof(SAVE_BITMAP_ORDER));
627
628
0
  if (!wParam)
629
0
    return FALSE;
630
631
0
  CopyMemory(wParam, saveBitmap, sizeof(SAVE_BITMAP_ORDER));
632
633
0
  up = update_cast(context->update);
634
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, SaveBitmap),
635
0
                           (void*)wParam, nullptr);
636
0
}
637
638
static BOOL update_message_GlyphIndex(rdpContext* context, GLYPH_INDEX_ORDER* glyphIndex)
639
0
{
640
0
  GLYPH_INDEX_ORDER* wParam = nullptr;
641
0
  rdp_update_internal* up = nullptr;
642
643
0
  if (!context || !context->update || !glyphIndex)
644
0
    return FALSE;
645
646
0
  wParam = (GLYPH_INDEX_ORDER*)malloc(sizeof(GLYPH_INDEX_ORDER));
647
648
0
  if (!wParam)
649
0
    return FALSE;
650
651
0
  CopyMemory(wParam, glyphIndex, sizeof(GLYPH_INDEX_ORDER));
652
0
  wParam->brush.data = (BYTE*)wParam->brush.p8x8;
653
654
0
  up = update_cast(context->update);
655
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, GlyphIndex),
656
0
                           (void*)wParam, nullptr);
657
0
}
658
659
static BOOL update_message_FastIndex(rdpContext* context, const FAST_INDEX_ORDER* fastIndex)
660
0
{
661
0
  FAST_INDEX_ORDER* wParam = nullptr;
662
0
  rdp_update_internal* up = nullptr;
663
664
0
  if (!context || !context->update || !fastIndex)
665
0
    return FALSE;
666
667
0
  wParam = (FAST_INDEX_ORDER*)malloc(sizeof(FAST_INDEX_ORDER));
668
669
0
  if (!wParam)
670
0
    return FALSE;
671
672
0
  CopyMemory(wParam, fastIndex, sizeof(FAST_INDEX_ORDER));
673
674
0
  up = update_cast(context->update);
675
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, FastIndex),
676
0
                           (void*)wParam, nullptr);
677
0
}
678
679
static BOOL update_message_FastGlyph(rdpContext* context, const FAST_GLYPH_ORDER* fastGlyph)
680
0
{
681
0
  FAST_GLYPH_ORDER* wParam = nullptr;
682
0
  rdp_update_internal* up = nullptr;
683
684
0
  if (!context || !context->update || !fastGlyph)
685
0
    return FALSE;
686
687
0
  wParam = (FAST_GLYPH_ORDER*)malloc(sizeof(FAST_GLYPH_ORDER));
688
689
0
  if (!wParam)
690
0
    return FALSE;
691
692
0
  CopyMemory(wParam, fastGlyph, sizeof(FAST_GLYPH_ORDER));
693
694
0
  if (wParam->cbData > 1)
695
0
  {
696
0
    wParam->glyphData.aj = (BYTE*)malloc(fastGlyph->glyphData.cb);
697
698
0
    if (!wParam->glyphData.aj)
699
0
    {
700
0
      free(wParam);
701
0
      return FALSE;
702
0
    }
703
704
0
    CopyMemory(wParam->glyphData.aj, fastGlyph->glyphData.aj, fastGlyph->glyphData.cb);
705
0
  }
706
0
  else
707
0
  {
708
0
    wParam->glyphData.aj = nullptr;
709
0
  }
710
711
0
  up = update_cast(context->update);
712
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, FastGlyph),
713
0
                           (void*)wParam, nullptr);
714
0
}
715
716
static BOOL update_message_PolygonSC(rdpContext* context, const POLYGON_SC_ORDER* polygonSC)
717
0
{
718
0
  if (!context || !context->update || !polygonSC)
719
0
    return FALSE;
720
721
0
  POLYGON_SC_ORDER* wParam = (POLYGON_SC_ORDER*)malloc(sizeof(POLYGON_SC_ORDER));
722
723
0
  if (!wParam)
724
0
    return FALSE;
725
726
0
  *wParam = *polygonSC;
727
0
  if (polygonSC->numPoints > 0)
728
0
  {
729
0
    wParam->points = (DELTA_POINT*)calloc(polygonSC->numPoints, sizeof(DELTA_POINT));
730
731
0
    if (!wParam->points)
732
0
    {
733
0
      free(wParam);
734
0
      return FALSE;
735
0
    }
736
737
0
    CopyMemory(wParam->points, polygonSC->points, sizeof(DELTA_POINT) * wParam->numPoints);
738
0
  }
739
0
  else
740
0
    wParam->points = nullptr;
741
742
0
  rdp_update_internal* up = update_cast(context->update);
743
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, PolygonSC),
744
0
                           (void*)wParam, nullptr);
745
0
}
746
747
static BOOL update_message_PolygonCB(rdpContext* context, POLYGON_CB_ORDER* polygonCB)
748
0
{
749
0
  if (!context || !context->update || !polygonCB)
750
0
    return FALSE;
751
752
0
  POLYGON_CB_ORDER* wParam = (POLYGON_CB_ORDER*)malloc(sizeof(POLYGON_CB_ORDER));
753
754
0
  if (!wParam)
755
0
    return FALSE;
756
757
0
  *wParam = *polygonCB;
758
0
  if (polygonCB->numPoints > 0)
759
0
  {
760
0
    wParam->points = (DELTA_POINT*)calloc(polygonCB->numPoints, sizeof(DELTA_POINT));
761
762
0
    if (!wParam->points)
763
0
    {
764
0
      free(wParam);
765
0
      return FALSE;
766
0
    }
767
768
0
    CopyMemory(wParam->points, polygonCB->points, sizeof(DELTA_POINT) * wParam->numPoints);
769
0
  }
770
0
  else
771
0
    wParam->points = nullptr;
772
773
0
  wParam->brush.data = (BYTE*)wParam->brush.p8x8;
774
775
0
  rdp_update_internal* up = update_cast(context->update);
776
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, PolygonCB),
777
0
                           (void*)wParam, nullptr);
778
0
}
779
780
static BOOL update_message_EllipseSC(rdpContext* context, const ELLIPSE_SC_ORDER* ellipseSC)
781
0
{
782
0
  if (!context || !context->update || !ellipseSC)
783
0
    return FALSE;
784
785
0
  ELLIPSE_SC_ORDER* wParam = (ELLIPSE_SC_ORDER*)malloc(sizeof(ELLIPSE_SC_ORDER));
786
787
0
  if (!wParam)
788
0
    return FALSE;
789
790
0
  CopyMemory(wParam, ellipseSC, sizeof(ELLIPSE_SC_ORDER));
791
792
0
  rdp_update_internal* up = update_cast(context->update);
793
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, EllipseSC),
794
0
                           (void*)wParam, nullptr);
795
0
}
796
797
static BOOL update_message_EllipseCB(rdpContext* context, const ELLIPSE_CB_ORDER* ellipseCB)
798
0
{
799
0
  ELLIPSE_CB_ORDER* wParam = nullptr;
800
0
  rdp_update_internal* up = nullptr;
801
802
0
  if (!context || !context->update || !ellipseCB)
803
0
    return FALSE;
804
805
0
  wParam = (ELLIPSE_CB_ORDER*)malloc(sizeof(ELLIPSE_CB_ORDER));
806
807
0
  if (!wParam)
808
0
    return FALSE;
809
810
0
  CopyMemory(wParam, ellipseCB, sizeof(ELLIPSE_CB_ORDER));
811
0
  wParam->brush.data = (BYTE*)wParam->brush.p8x8;
812
813
0
  up = update_cast(context->update);
814
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PrimaryUpdate, EllipseCB),
815
0
                           (void*)wParam, nullptr);
816
0
}
817
818
/* Secondary Update */
819
820
static BOOL update_message_CacheBitmap(rdpContext* context,
821
                                       const CACHE_BITMAP_ORDER* cacheBitmapOrder)
822
0
{
823
0
  CACHE_BITMAP_ORDER* wParam = nullptr;
824
0
  rdp_update_internal* up = nullptr;
825
826
0
  if (!context || !context->update || !cacheBitmapOrder)
827
0
    return FALSE;
828
829
0
  wParam = copy_cache_bitmap_order(context, cacheBitmapOrder);
830
831
0
  if (!wParam)
832
0
    return FALSE;
833
834
0
  up = update_cast(context->update);
835
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(SecondaryUpdate, CacheBitmap),
836
0
                           (void*)wParam, nullptr);
837
0
}
838
839
static BOOL update_message_CacheBitmapV2(rdpContext* context,
840
                                         CACHE_BITMAP_V2_ORDER* cacheBitmapV2Order)
841
0
{
842
0
  CACHE_BITMAP_V2_ORDER* wParam = nullptr;
843
0
  rdp_update_internal* up = nullptr;
844
845
0
  if (!context || !context->update || !cacheBitmapV2Order)
846
0
    return FALSE;
847
848
0
  wParam = copy_cache_bitmap_v2_order(context, cacheBitmapV2Order);
849
850
0
  if (!wParam)
851
0
    return FALSE;
852
853
0
  up = update_cast(context->update);
854
0
  return MessageQueue_Post(up->queue, (void*)context,
855
0
                           MakeMessageId(SecondaryUpdate, CacheBitmapV2), (void*)wParam, nullptr);
856
0
}
857
858
static BOOL update_message_CacheBitmapV3(rdpContext* context,
859
                                         CACHE_BITMAP_V3_ORDER* cacheBitmapV3Order)
860
0
{
861
0
  CACHE_BITMAP_V3_ORDER* wParam = nullptr;
862
0
  rdp_update_internal* up = nullptr;
863
864
0
  if (!context || !context->update || !cacheBitmapV3Order)
865
0
    return FALSE;
866
867
0
  wParam = copy_cache_bitmap_v3_order(context, cacheBitmapV3Order);
868
869
0
  if (!wParam)
870
0
    return FALSE;
871
872
0
  up = update_cast(context->update);
873
0
  return MessageQueue_Post(up->queue, (void*)context,
874
0
                           MakeMessageId(SecondaryUpdate, CacheBitmapV3), (void*)wParam, nullptr);
875
0
}
876
877
static BOOL update_message_CacheColorTable(rdpContext* context,
878
                                           const CACHE_COLOR_TABLE_ORDER* cacheColorTableOrder)
879
0
{
880
0
  CACHE_COLOR_TABLE_ORDER* wParam = nullptr;
881
0
  rdp_update_internal* up = nullptr;
882
883
0
  if (!context || !context->update || !cacheColorTableOrder)
884
0
    return FALSE;
885
886
0
  wParam = copy_cache_color_table_order(context, cacheColorTableOrder);
887
888
0
  if (!wParam)
889
0
    return FALSE;
890
891
0
  up = update_cast(context->update);
892
0
  return MessageQueue_Post(up->queue, (void*)context,
893
0
                           MakeMessageId(SecondaryUpdate, CacheColorTable), (void*)wParam,
894
0
                           nullptr);
895
0
}
896
897
static BOOL update_message_CacheGlyph(rdpContext* context, const CACHE_GLYPH_ORDER* cacheGlyphOrder)
898
0
{
899
0
  CACHE_GLYPH_ORDER* wParam = nullptr;
900
0
  rdp_update_internal* up = nullptr;
901
902
0
  if (!context || !context->update || !cacheGlyphOrder)
903
0
    return FALSE;
904
905
0
  wParam = copy_cache_glyph_order(context, cacheGlyphOrder);
906
907
0
  if (!wParam)
908
0
    return FALSE;
909
910
0
  up = update_cast(context->update);
911
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(SecondaryUpdate, CacheGlyph),
912
0
                           (void*)wParam, nullptr);
913
0
}
914
915
static BOOL update_message_CacheGlyphV2(rdpContext* context,
916
                                        const CACHE_GLYPH_V2_ORDER* cacheGlyphV2Order)
917
0
{
918
0
  CACHE_GLYPH_V2_ORDER* wParam = nullptr;
919
0
  rdp_update_internal* up = nullptr;
920
921
0
  if (!context || !context->update || !cacheGlyphV2Order)
922
0
    return FALSE;
923
924
0
  wParam = copy_cache_glyph_v2_order(context, cacheGlyphV2Order);
925
926
0
  if (!wParam)
927
0
    return FALSE;
928
929
0
  up = update_cast(context->update);
930
0
  return MessageQueue_Post(up->queue, (void*)context,
931
0
                           MakeMessageId(SecondaryUpdate, CacheGlyphV2), (void*)wParam, nullptr);
932
0
}
933
934
static BOOL update_message_CacheBrush(rdpContext* context, const CACHE_BRUSH_ORDER* cacheBrushOrder)
935
0
{
936
0
  CACHE_BRUSH_ORDER* wParam = nullptr;
937
0
  rdp_update_internal* up = nullptr;
938
939
0
  if (!context || !context->update || !cacheBrushOrder)
940
0
    return FALSE;
941
942
0
  wParam = copy_cache_brush_order(context, cacheBrushOrder);
943
944
0
  if (!wParam)
945
0
    return FALSE;
946
947
0
  up = update_cast(context->update);
948
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(SecondaryUpdate, CacheBrush),
949
0
                           (void*)wParam, nullptr);
950
0
}
951
952
/* Alternate Secondary Update */
953
954
static BOOL
955
update_message_CreateOffscreenBitmap(rdpContext* context,
956
                                     const CREATE_OFFSCREEN_BITMAP_ORDER* createOffscreenBitmap)
957
0
{
958
0
  CREATE_OFFSCREEN_BITMAP_ORDER* wParam = nullptr;
959
0
  rdp_update_internal* up = nullptr;
960
961
0
  if (!context || !context->update || !createOffscreenBitmap)
962
0
    return FALSE;
963
964
0
  wParam = (CREATE_OFFSCREEN_BITMAP_ORDER*)malloc(sizeof(CREATE_OFFSCREEN_BITMAP_ORDER));
965
966
0
  if (!wParam)
967
0
    return FALSE;
968
969
0
  CopyMemory(wParam, createOffscreenBitmap, sizeof(CREATE_OFFSCREEN_BITMAP_ORDER));
970
0
  wParam->deleteList.cIndices = createOffscreenBitmap->deleteList.cIndices;
971
0
  wParam->deleteList.sIndices = wParam->deleteList.cIndices;
972
0
  wParam->deleteList.indices = (UINT16*)calloc(wParam->deleteList.cIndices, sizeof(UINT16));
973
974
0
  if (!wParam->deleteList.indices)
975
0
  {
976
0
    free(wParam);
977
0
    return FALSE;
978
0
  }
979
980
0
  CopyMemory(wParam->deleteList.indices, createOffscreenBitmap->deleteList.indices,
981
0
             wParam->deleteList.cIndices);
982
983
0
  up = update_cast(context->update);
984
0
  return MessageQueue_Post(up->queue, (void*)context,
985
0
                           MakeMessageId(AltSecUpdate, CreateOffscreenBitmap), (void*)wParam,
986
0
                           nullptr);
987
0
}
988
989
static BOOL update_message_SwitchSurface(rdpContext* context,
990
                                         const SWITCH_SURFACE_ORDER* switchSurface)
991
0
{
992
0
  SWITCH_SURFACE_ORDER* wParam = nullptr;
993
0
  rdp_update_internal* up = nullptr;
994
995
0
  if (!context || !context->update || !switchSurface)
996
0
    return FALSE;
997
998
0
  wParam = (SWITCH_SURFACE_ORDER*)malloc(sizeof(SWITCH_SURFACE_ORDER));
999
1000
0
  if (!wParam)
1001
0
    return FALSE;
1002
1003
0
  CopyMemory(wParam, switchSurface, sizeof(SWITCH_SURFACE_ORDER));
1004
1005
0
  up = update_cast(context->update);
1006
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(AltSecUpdate, SwitchSurface),
1007
0
                           (void*)wParam, nullptr);
1008
0
}
1009
1010
static BOOL
1011
update_message_CreateNineGridBitmap(rdpContext* context,
1012
                                    const CREATE_NINE_GRID_BITMAP_ORDER* createNineGridBitmap)
1013
0
{
1014
0
  CREATE_NINE_GRID_BITMAP_ORDER* wParam = nullptr;
1015
0
  rdp_update_internal* up = nullptr;
1016
1017
0
  if (!context || !context->update || !createNineGridBitmap)
1018
0
    return FALSE;
1019
1020
0
  wParam = (CREATE_NINE_GRID_BITMAP_ORDER*)malloc(sizeof(CREATE_NINE_GRID_BITMAP_ORDER));
1021
1022
0
  if (!wParam)
1023
0
    return FALSE;
1024
1025
0
  CopyMemory(wParam, createNineGridBitmap, sizeof(CREATE_NINE_GRID_BITMAP_ORDER));
1026
1027
0
  up = update_cast(context->update);
1028
0
  return MessageQueue_Post(up->queue, (void*)context,
1029
0
                           MakeMessageId(AltSecUpdate, CreateNineGridBitmap), (void*)wParam,
1030
0
                           nullptr);
1031
0
}
1032
1033
static BOOL update_message_FrameMarker(rdpContext* context, const FRAME_MARKER_ORDER* frameMarker)
1034
0
{
1035
0
  FRAME_MARKER_ORDER* wParam = nullptr;
1036
0
  rdp_update_internal* up = nullptr;
1037
1038
0
  if (!context || !context->update || !frameMarker)
1039
0
    return FALSE;
1040
1041
0
  wParam = (FRAME_MARKER_ORDER*)malloc(sizeof(FRAME_MARKER_ORDER));
1042
1043
0
  if (!wParam)
1044
0
    return FALSE;
1045
1046
0
  CopyMemory(wParam, frameMarker, sizeof(FRAME_MARKER_ORDER));
1047
1048
0
  up = update_cast(context->update);
1049
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(AltSecUpdate, FrameMarker),
1050
0
                           (void*)wParam, nullptr);
1051
0
}
1052
1053
static BOOL update_message_StreamBitmapFirst(rdpContext* context,
1054
                                             const STREAM_BITMAP_FIRST_ORDER* streamBitmapFirst)
1055
0
{
1056
0
  STREAM_BITMAP_FIRST_ORDER* wParam = nullptr;
1057
0
  rdp_update_internal* up = nullptr;
1058
1059
0
  if (!context || !context->update || !streamBitmapFirst)
1060
0
    return FALSE;
1061
1062
0
  wParam = (STREAM_BITMAP_FIRST_ORDER*)malloc(sizeof(STREAM_BITMAP_FIRST_ORDER));
1063
1064
0
  if (!wParam)
1065
0
    return FALSE;
1066
1067
0
  CopyMemory(wParam, streamBitmapFirst, sizeof(STREAM_BITMAP_FIRST_ORDER));
1068
  /* TODO: complete copy */
1069
1070
0
  up = update_cast(context->update);
1071
0
  return MessageQueue_Post(up->queue, (void*)context,
1072
0
                           MakeMessageId(AltSecUpdate, StreamBitmapFirst), (void*)wParam,
1073
0
                           nullptr);
1074
0
}
1075
1076
static BOOL update_message_StreamBitmapNext(rdpContext* context,
1077
                                            const STREAM_BITMAP_NEXT_ORDER* streamBitmapNext)
1078
0
{
1079
0
  STREAM_BITMAP_NEXT_ORDER* wParam = nullptr;
1080
0
  rdp_update_internal* up = nullptr;
1081
1082
0
  if (!context || !context->update || !streamBitmapNext)
1083
0
    return FALSE;
1084
1085
0
  wParam = (STREAM_BITMAP_NEXT_ORDER*)malloc(sizeof(STREAM_BITMAP_NEXT_ORDER));
1086
1087
0
  if (!wParam)
1088
0
    return FALSE;
1089
1090
0
  CopyMemory(wParam, streamBitmapNext, sizeof(STREAM_BITMAP_NEXT_ORDER));
1091
  /* TODO: complete copy */
1092
1093
0
  up = update_cast(context->update);
1094
0
  return MessageQueue_Post(up->queue, (void*)context,
1095
0
                           MakeMessageId(AltSecUpdate, StreamBitmapNext), (void*)wParam, nullptr);
1096
0
}
1097
1098
static BOOL update_message_DrawGdiPlusFirst(rdpContext* context,
1099
                                            const DRAW_GDIPLUS_FIRST_ORDER* drawGdiPlusFirst)
1100
0
{
1101
0
  DRAW_GDIPLUS_FIRST_ORDER* wParam = nullptr;
1102
0
  rdp_update_internal* up = nullptr;
1103
1104
0
  if (!context || !context->update || !drawGdiPlusFirst)
1105
0
    return FALSE;
1106
1107
0
  wParam = (DRAW_GDIPLUS_FIRST_ORDER*)malloc(sizeof(DRAW_GDIPLUS_FIRST_ORDER));
1108
1109
0
  if (!wParam)
1110
0
    return FALSE;
1111
1112
0
  CopyMemory(wParam, drawGdiPlusFirst, sizeof(DRAW_GDIPLUS_FIRST_ORDER));
1113
  /* TODO: complete copy */
1114
0
  up = update_cast(context->update);
1115
0
  return MessageQueue_Post(up->queue, (void*)context,
1116
0
                           MakeMessageId(AltSecUpdate, DrawGdiPlusFirst), (void*)wParam, nullptr);
1117
0
}
1118
1119
static BOOL update_message_DrawGdiPlusNext(rdpContext* context,
1120
                                           const DRAW_GDIPLUS_NEXT_ORDER* drawGdiPlusNext)
1121
0
{
1122
0
  DRAW_GDIPLUS_NEXT_ORDER* wParam = nullptr;
1123
0
  rdp_update_internal* up = nullptr;
1124
1125
0
  if (!context || !context->update || !drawGdiPlusNext)
1126
0
    return FALSE;
1127
1128
0
  wParam = (DRAW_GDIPLUS_NEXT_ORDER*)malloc(sizeof(DRAW_GDIPLUS_NEXT_ORDER));
1129
1130
0
  if (!wParam)
1131
0
    return FALSE;
1132
1133
0
  CopyMemory(wParam, drawGdiPlusNext, sizeof(DRAW_GDIPLUS_NEXT_ORDER));
1134
  /* TODO: complete copy */
1135
1136
0
  up = update_cast(context->update);
1137
0
  return MessageQueue_Post(up->queue, (void*)context,
1138
0
                           MakeMessageId(AltSecUpdate, DrawGdiPlusNext), (void*)wParam, nullptr);
1139
0
}
1140
1141
static BOOL update_message_DrawGdiPlusEnd(rdpContext* context,
1142
                                          const DRAW_GDIPLUS_END_ORDER* drawGdiPlusEnd)
1143
0
{
1144
0
  DRAW_GDIPLUS_END_ORDER* wParam = nullptr;
1145
0
  rdp_update_internal* up = nullptr;
1146
1147
0
  if (!context || !context->update || !drawGdiPlusEnd)
1148
0
    return FALSE;
1149
1150
0
  wParam = (DRAW_GDIPLUS_END_ORDER*)malloc(sizeof(DRAW_GDIPLUS_END_ORDER));
1151
1152
0
  if (!wParam)
1153
0
    return FALSE;
1154
1155
0
  CopyMemory(wParam, drawGdiPlusEnd, sizeof(DRAW_GDIPLUS_END_ORDER));
1156
  /* TODO: complete copy */
1157
1158
0
  up = update_cast(context->update);
1159
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(AltSecUpdate, DrawGdiPlusEnd),
1160
0
                           (void*)wParam, nullptr);
1161
0
}
1162
1163
static BOOL
1164
update_message_DrawGdiPlusCacheFirst(rdpContext* context,
1165
                                     const DRAW_GDIPLUS_CACHE_FIRST_ORDER* drawGdiPlusCacheFirst)
1166
0
{
1167
0
  DRAW_GDIPLUS_CACHE_FIRST_ORDER* wParam = nullptr;
1168
0
  rdp_update_internal* up = nullptr;
1169
1170
0
  if (!context || !context->update || !drawGdiPlusCacheFirst)
1171
0
    return FALSE;
1172
1173
0
  wParam = (DRAW_GDIPLUS_CACHE_FIRST_ORDER*)malloc(sizeof(DRAW_GDIPLUS_CACHE_FIRST_ORDER));
1174
1175
0
  if (!wParam)
1176
0
    return FALSE;
1177
1178
0
  CopyMemory(wParam, drawGdiPlusCacheFirst, sizeof(DRAW_GDIPLUS_CACHE_FIRST_ORDER));
1179
  /* TODO: complete copy */
1180
1181
0
  up = update_cast(context->update);
1182
0
  return MessageQueue_Post(up->queue, (void*)context,
1183
0
                           MakeMessageId(AltSecUpdate, DrawGdiPlusCacheFirst), (void*)wParam,
1184
0
                           nullptr);
1185
0
}
1186
1187
static BOOL
1188
update_message_DrawGdiPlusCacheNext(rdpContext* context,
1189
                                    const DRAW_GDIPLUS_CACHE_NEXT_ORDER* drawGdiPlusCacheNext)
1190
0
{
1191
0
  DRAW_GDIPLUS_CACHE_NEXT_ORDER* wParam = nullptr;
1192
0
  rdp_update_internal* up = nullptr;
1193
1194
0
  if (!context || !context->update || !drawGdiPlusCacheNext)
1195
0
    return FALSE;
1196
1197
0
  wParam = (DRAW_GDIPLUS_CACHE_NEXT_ORDER*)malloc(sizeof(DRAW_GDIPLUS_CACHE_NEXT_ORDER));
1198
1199
0
  if (!wParam)
1200
0
    return FALSE;
1201
1202
0
  CopyMemory(wParam, drawGdiPlusCacheNext, sizeof(DRAW_GDIPLUS_CACHE_NEXT_ORDER));
1203
  /* TODO: complete copy */
1204
1205
0
  up = update_cast(context->update);
1206
0
  return MessageQueue_Post(up->queue, (void*)context,
1207
0
                           MakeMessageId(AltSecUpdate, DrawGdiPlusCacheNext), (void*)wParam,
1208
0
                           nullptr);
1209
0
}
1210
1211
static BOOL
1212
update_message_DrawGdiPlusCacheEnd(rdpContext* context,
1213
                                   const DRAW_GDIPLUS_CACHE_END_ORDER* drawGdiPlusCacheEnd)
1214
0
{
1215
0
  DRAW_GDIPLUS_CACHE_END_ORDER* wParam = nullptr;
1216
0
  rdp_update_internal* up = nullptr;
1217
1218
0
  if (!context || !context->update || !drawGdiPlusCacheEnd)
1219
0
    return FALSE;
1220
1221
0
  wParam = (DRAW_GDIPLUS_CACHE_END_ORDER*)malloc(sizeof(DRAW_GDIPLUS_CACHE_END_ORDER));
1222
1223
0
  if (!wParam)
1224
0
    return FALSE;
1225
1226
0
  CopyMemory(wParam, drawGdiPlusCacheEnd, sizeof(DRAW_GDIPLUS_CACHE_END_ORDER));
1227
  /* TODO: complete copy */
1228
1229
0
  up = update_cast(context->update);
1230
0
  return MessageQueue_Post(up->queue, (void*)context,
1231
0
                           MakeMessageId(AltSecUpdate, DrawGdiPlusCacheEnd), (void*)wParam,
1232
0
                           nullptr);
1233
0
}
1234
1235
/* Window Update */
1236
static RAIL_UNICODE_STRING rail_unicode_string_clone(const RAIL_UNICODE_STRING* str)
1237
0
{
1238
0
  WINPR_ASSERT(str);
1239
0
  WINPR_ASSERT(((str->length == 0) && (str->string == nullptr)) ||
1240
0
               (str->length == _wcsnlen(str->string, str->length)));
1241
0
  RAIL_UNICODE_STRING clone = { .string = wcsndup(str->string, str->length),
1242
0
                              .length = str->length };
1243
0
  return clone;
1244
0
}
1245
1246
static void window_state_order_free(WINDOW_STATE_ORDER* order)
1247
0
{
1248
0
  if (!order)
1249
0
    return;
1250
0
  free(order->windowRects);
1251
0
  free(order->visibilityRects);
1252
0
  rail_unicode_string_free(&order->titleInfo);
1253
0
  rail_unicode_string_free(&order->OverlayDescription);
1254
1255
0
  free(order);
1256
0
}
1257
1258
static WINDOW_STATE_ORDER* window_state_order_clone(const WINDOW_STATE_ORDER* order)
1259
0
{
1260
0
  WINDOW_STATE_ORDER* clone = calloc(1, sizeof(WINDOW_STATE_ORDER));
1261
0
  if (!clone)
1262
0
    return nullptr;
1263
0
  *clone = *order;
1264
1265
0
  clone->titleInfo = rail_unicode_string_clone(&order->titleInfo);
1266
0
  clone->OverlayDescription = rail_unicode_string_clone(&order->OverlayDescription);
1267
0
  clone->windowRects = rectangles_clone(order->windowRects, order->numWindowRects);
1268
0
  clone->visibilityRects = rectangles_clone(order->visibilityRects, order->numVisibilityRects);
1269
0
  if ((!clone->windowRects && (clone->numWindowRects > 0)) ||
1270
0
      (!clone->visibilityRects && (clone->numVisibilityRects > 0)) ||
1271
0
      (!clone->titleInfo.string && (clone->titleInfo.length > 0)) ||
1272
0
      (!clone->OverlayDescription.string && (clone->OverlayDescription.length > 0)))
1273
0
  {
1274
0
    window_state_order_free(clone);
1275
0
    return nullptr;
1276
0
  }
1277
0
  return clone;
1278
0
}
1279
1280
static BOOL update_message_WindowCreate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1281
                                        const WINDOW_STATE_ORDER* windowState)
1282
0
{
1283
0
  if (!context || !context->update || !orderInfo || !windowState)
1284
0
    return FALSE;
1285
1286
0
  WINDOW_ORDER_INFO* wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1287
1288
0
  if (!wParam)
1289
0
    return FALSE;
1290
1291
0
  *wParam = *orderInfo;
1292
1293
0
  WINDOW_STATE_ORDER* lParam = window_state_order_clone(windowState);
1294
1295
0
  if (!lParam)
1296
0
  {
1297
0
    free(wParam);
1298
0
    return FALSE;
1299
0
  }
1300
1301
0
  rdp_update_internal* up = update_cast(context->update);
1302
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(WindowUpdate, WindowCreate),
1303
0
                           (void*)wParam, (void*)lParam);
1304
0
}
1305
1306
static BOOL update_message_WindowUpdate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1307
                                        const WINDOW_STATE_ORDER* windowState)
1308
0
{
1309
0
  if (!context || !context->update || !orderInfo || !windowState)
1310
0
    return FALSE;
1311
1312
0
  WINDOW_ORDER_INFO* wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1313
1314
0
  if (!wParam)
1315
0
    return FALSE;
1316
1317
0
  *wParam = *orderInfo;
1318
1319
0
  WINDOW_STATE_ORDER* lParam = window_state_order_clone(windowState);
1320
1321
0
  if (!lParam)
1322
0
  {
1323
0
    free(wParam);
1324
0
    return FALSE;
1325
0
  }
1326
1327
0
  rdp_update_internal* up = update_cast(context->update);
1328
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(WindowUpdate, WindowUpdate),
1329
0
                           (void*)wParam, (void*)lParam);
1330
0
}
1331
1332
static BOOL update_message_WindowIcon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1333
                                      const WINDOW_ICON_ORDER* windowIcon)
1334
0
{
1335
0
  if (!context || !context->update || !orderInfo || !windowIcon)
1336
0
    return FALSE;
1337
1338
0
  WINDOW_ORDER_INFO* wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1339
1340
0
  if (!wParam)
1341
0
    return FALSE;
1342
1343
0
  *wParam = *orderInfo;
1344
1345
0
  WINDOW_ICON_ORDER* lParam = (WINDOW_ICON_ORDER*)calloc(1, sizeof(WINDOW_ICON_ORDER));
1346
1347
0
  if (!lParam)
1348
0
    goto out_fail;
1349
1350
0
  *lParam = *windowIcon;
1351
0
  lParam->iconInfo = calloc(1, sizeof(ICON_INFO));
1352
1353
0
  if (!lParam->iconInfo)
1354
0
    goto out_fail;
1355
1356
0
  *lParam->iconInfo = *windowIcon->iconInfo;
1357
1358
0
  WLog_VRB(TAG, "update_message_WindowIcon");
1359
1360
0
  if (windowIcon->iconInfo->cbBitsColor > 0)
1361
0
  {
1362
0
    lParam->iconInfo->bitsColor = (BYTE*)malloc(windowIcon->iconInfo->cbBitsColor);
1363
1364
0
    if (!lParam->iconInfo->bitsColor)
1365
0
      goto out_fail;
1366
1367
0
    CopyMemory(lParam->iconInfo->bitsColor, windowIcon->iconInfo->bitsColor,
1368
0
               windowIcon->iconInfo->cbBitsColor);
1369
0
  }
1370
1371
0
  if (windowIcon->iconInfo->cbBitsMask > 0)
1372
0
  {
1373
0
    lParam->iconInfo->bitsMask = (BYTE*)malloc(windowIcon->iconInfo->cbBitsMask);
1374
1375
0
    if (!lParam->iconInfo->bitsMask)
1376
0
      goto out_fail;
1377
1378
0
    CopyMemory(lParam->iconInfo->bitsMask, windowIcon->iconInfo->bitsMask,
1379
0
               windowIcon->iconInfo->cbBitsMask);
1380
0
  }
1381
1382
0
  if (windowIcon->iconInfo->cbColorTable > 0)
1383
0
  {
1384
0
    lParam->iconInfo->colorTable = (BYTE*)malloc(windowIcon->iconInfo->cbColorTable);
1385
1386
0
    if (!lParam->iconInfo->colorTable)
1387
0
      goto out_fail;
1388
1389
0
    CopyMemory(lParam->iconInfo->colorTable, windowIcon->iconInfo->colorTable,
1390
0
               windowIcon->iconInfo->cbColorTable);
1391
0
  }
1392
1393
0
  rdp_update_internal* up = update_cast(context->update);
1394
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(WindowUpdate, WindowIcon),
1395
0
                           (void*)wParam, (void*)lParam);
1396
0
out_fail:
1397
1398
0
  if (lParam && lParam->iconInfo)
1399
0
  {
1400
0
    free(lParam->iconInfo->bitsColor);
1401
0
    free(lParam->iconInfo->bitsMask);
1402
0
    free(lParam->iconInfo->colorTable);
1403
0
    free(lParam->iconInfo);
1404
0
  }
1405
1406
0
  free(lParam);
1407
0
  free(wParam);
1408
0
  return FALSE;
1409
0
}
1410
1411
static BOOL update_message_WindowCachedIcon(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1412
                                            const WINDOW_CACHED_ICON_ORDER* windowCachedIcon)
1413
0
{
1414
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1415
0
  WINDOW_CACHED_ICON_ORDER* lParam = nullptr;
1416
0
  rdp_update_internal* up = nullptr;
1417
1418
0
  if (!context || !context->update || !orderInfo || !windowCachedIcon)
1419
0
    return FALSE;
1420
1421
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1422
1423
0
  if (!wParam)
1424
0
    return FALSE;
1425
1426
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1427
0
  lParam = (WINDOW_CACHED_ICON_ORDER*)malloc(sizeof(WINDOW_CACHED_ICON_ORDER));
1428
1429
0
  if (!lParam)
1430
0
  {
1431
0
    free(wParam);
1432
0
    return FALSE;
1433
0
  }
1434
1435
0
  CopyMemory(lParam, windowCachedIcon, sizeof(WINDOW_CACHED_ICON_ORDER));
1436
1437
0
  up = update_cast(context->update);
1438
0
  return MessageQueue_Post(up->queue, (void*)context,
1439
0
                           MakeMessageId(WindowUpdate, WindowCachedIcon), (void*)wParam,
1440
0
                           (void*)lParam);
1441
0
}
1442
1443
static BOOL update_message_WindowDelete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo)
1444
0
{
1445
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1446
0
  rdp_update_internal* up = nullptr;
1447
1448
0
  if (!context || !context->update || !orderInfo)
1449
0
    return FALSE;
1450
1451
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1452
1453
0
  if (!wParam)
1454
0
    return FALSE;
1455
1456
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1457
1458
0
  up = update_cast(context->update);
1459
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(WindowUpdate, WindowDelete),
1460
0
                           (void*)wParam, nullptr);
1461
0
}
1462
1463
static void notify_icon_state_order_free(NOTIFY_ICON_STATE_ORDER* notify)
1464
0
{
1465
0
  if (!notify)
1466
0
    return;
1467
1468
0
  rail_unicode_string_free(&notify->toolTip);
1469
0
  rail_unicode_string_free(&notify->infoTip.text);
1470
0
  rail_unicode_string_free(&notify->infoTip.title);
1471
0
  free(notify->icon.bitsColor);
1472
0
  free(notify->icon.bitsMask);
1473
0
  free(notify->icon.colorTable);
1474
0
  free(notify);
1475
0
}
1476
1477
static BOOL icon_info_clone(ICON_INFO* dst, const ICON_INFO* src)
1478
0
{
1479
0
  dst->bitsColor = nullptr;
1480
0
  dst->bitsMask = nullptr;
1481
0
  dst->colorTable = nullptr;
1482
1483
0
  if (src->cbBitsColor > 0)
1484
0
  {
1485
0
    dst->bitsColor = (BYTE*)malloc(src->cbBitsColor);
1486
0
    if (!dst->bitsColor)
1487
0
      return FALSE;
1488
0
    CopyMemory(dst->bitsColor, src->bitsColor, src->cbBitsColor);
1489
0
  }
1490
1491
0
  if (src->cbBitsMask > 0)
1492
0
  {
1493
0
    dst->bitsMask = (BYTE*)malloc(src->cbBitsMask);
1494
0
    if (!dst->bitsMask)
1495
0
      return FALSE;
1496
0
    CopyMemory(dst->bitsMask, src->bitsMask, src->cbBitsMask);
1497
0
  }
1498
1499
0
  if (src->cbColorTable > 0)
1500
0
  {
1501
0
    dst->colorTable = (BYTE*)malloc(src->cbColorTable);
1502
0
    if (!dst->colorTable)
1503
0
      return FALSE;
1504
0
    CopyMemory(dst->colorTable, src->colorTable, src->cbColorTable);
1505
0
  }
1506
1507
0
  return TRUE;
1508
0
}
1509
1510
static NOTIFY_ICON_STATE_ORDER* notify_icon_state_order_clone(const NOTIFY_ICON_STATE_ORDER* order)
1511
0
{
1512
0
  NOTIFY_ICON_STATE_ORDER* clone = calloc(1, sizeof(NOTIFY_ICON_STATE_ORDER));
1513
0
  if (!clone)
1514
0
    return nullptr;
1515
1516
0
  *clone = *order;
1517
0
  clone->toolTip = rail_unicode_string_clone(&order->toolTip);
1518
0
  clone->infoTip.text = rail_unicode_string_clone(&order->infoTip.text);
1519
0
  clone->infoTip.title = rail_unicode_string_clone(&order->infoTip.title);
1520
1521
0
  if (!icon_info_clone(&clone->icon, &order->icon) ||
1522
0
      (!clone->toolTip.string && (order->toolTip.length > 0)) ||
1523
0
      (!clone->infoTip.text.string && (order->infoTip.text.length > 0)) ||
1524
0
      (!clone->infoTip.title.string && (order->infoTip.title.length > 0)))
1525
0
  {
1526
0
    notify_icon_state_order_free(clone);
1527
0
    return nullptr;
1528
0
  }
1529
1530
0
  return clone;
1531
0
}
1532
1533
static BOOL update_message_NotifyIconCreate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1534
                                            const NOTIFY_ICON_STATE_ORDER* notifyIconState)
1535
0
{
1536
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1537
0
  NOTIFY_ICON_STATE_ORDER* lParam = nullptr;
1538
0
  rdp_update_internal* up = nullptr;
1539
1540
0
  if (!context || !context->update || !orderInfo || !notifyIconState)
1541
0
    return FALSE;
1542
1543
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1544
1545
0
  if (!wParam)
1546
0
    return FALSE;
1547
1548
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1549
0
  lParam = notify_icon_state_order_clone(notifyIconState);
1550
1551
0
  if (!lParam)
1552
0
  {
1553
0
    free(wParam);
1554
0
    return FALSE;
1555
0
  }
1556
1557
0
  up = update_cast(context->update);
1558
0
  return MessageQueue_Post(up->queue, (void*)context,
1559
0
                           MakeMessageId(WindowUpdate, NotifyIconCreate), (void*)wParam,
1560
0
                           (void*)lParam);
1561
0
}
1562
1563
static BOOL update_message_NotifyIconUpdate(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1564
                                            const NOTIFY_ICON_STATE_ORDER* notifyIconState)
1565
0
{
1566
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1567
0
  NOTIFY_ICON_STATE_ORDER* lParam = nullptr;
1568
0
  rdp_update_internal* up = nullptr;
1569
1570
0
  if (!context || !context->update || !orderInfo || !notifyIconState)
1571
0
    return FALSE;
1572
1573
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1574
1575
0
  if (!wParam)
1576
0
    return FALSE;
1577
1578
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1579
0
  lParam = notify_icon_state_order_clone(notifyIconState);
1580
1581
0
  if (!lParam)
1582
0
  {
1583
0
    free(wParam);
1584
0
    return FALSE;
1585
0
  }
1586
1587
0
  up = update_cast(context->update);
1588
0
  return MessageQueue_Post(up->queue, (void*)context,
1589
0
                           MakeMessageId(WindowUpdate, NotifyIconUpdate), (void*)wParam,
1590
0
                           (void*)lParam);
1591
0
}
1592
1593
static BOOL update_message_NotifyIconDelete(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo)
1594
0
{
1595
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1596
0
  rdp_update_internal* up = nullptr;
1597
1598
0
  if (!context || !context->update || !orderInfo)
1599
0
    return FALSE;
1600
1601
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1602
1603
0
  if (!wParam)
1604
0
    return FALSE;
1605
1606
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1607
1608
0
  up = update_cast(context->update);
1609
0
  return MessageQueue_Post(up->queue, (void*)context,
1610
0
                           MakeMessageId(WindowUpdate, NotifyIconDelete), (void*)wParam, nullptr);
1611
0
}
1612
1613
static BOOL update_message_MonitoredDesktop(rdpContext* context, const WINDOW_ORDER_INFO* orderInfo,
1614
                                            const MONITORED_DESKTOP_ORDER* monitoredDesktop)
1615
0
{
1616
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1617
0
  MONITORED_DESKTOP_ORDER* lParam = nullptr;
1618
0
  rdp_update_internal* up = nullptr;
1619
1620
0
  if (!context || !context->update || !orderInfo || !monitoredDesktop)
1621
0
    return FALSE;
1622
1623
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1624
1625
0
  if (!wParam)
1626
0
    return FALSE;
1627
1628
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1629
0
  lParam = (MONITORED_DESKTOP_ORDER*)malloc(sizeof(MONITORED_DESKTOP_ORDER));
1630
1631
0
  if (!lParam)
1632
0
  {
1633
0
    free(wParam);
1634
0
    return FALSE;
1635
0
  }
1636
1637
0
  CopyMemory(lParam, monitoredDesktop, sizeof(MONITORED_DESKTOP_ORDER));
1638
0
  lParam->windowIds = nullptr;
1639
1640
0
  if (lParam->numWindowIds)
1641
0
  {
1642
0
    lParam->windowIds = (UINT32*)calloc(lParam->numWindowIds, sizeof(UINT32));
1643
0
    CopyMemory(lParam->windowIds, monitoredDesktop->windowIds, lParam->numWindowIds);
1644
0
  }
1645
1646
0
  up = update_cast(context->update);
1647
0
  return MessageQueue_Post(up->queue, (void*)context,
1648
0
                           MakeMessageId(WindowUpdate, MonitoredDesktop), (void*)wParam,
1649
0
                           (void*)lParam);
1650
0
}
1651
1652
static BOOL update_message_NonMonitoredDesktop(rdpContext* context,
1653
                                               const WINDOW_ORDER_INFO* orderInfo)
1654
0
{
1655
0
  WINDOW_ORDER_INFO* wParam = nullptr;
1656
0
  rdp_update_internal* up = nullptr;
1657
1658
0
  if (!context || !context->update || !orderInfo)
1659
0
    return FALSE;
1660
1661
0
  wParam = (WINDOW_ORDER_INFO*)malloc(sizeof(WINDOW_ORDER_INFO));
1662
1663
0
  if (!wParam)
1664
0
    return FALSE;
1665
1666
0
  CopyMemory(wParam, orderInfo, sizeof(WINDOW_ORDER_INFO));
1667
1668
0
  up = update_cast(context->update);
1669
0
  return MessageQueue_Post(up->queue, (void*)context,
1670
0
                           MakeMessageId(WindowUpdate, NonMonitoredDesktop), (void*)wParam,
1671
0
                           nullptr);
1672
0
}
1673
1674
/* Pointer Update */
1675
1676
static BOOL update_message_PointerPosition(rdpContext* context,
1677
                                           const POINTER_POSITION_UPDATE* pointerPosition)
1678
0
{
1679
0
  POINTER_POSITION_UPDATE* wParam = nullptr;
1680
0
  rdp_update_internal* up = nullptr;
1681
1682
0
  if (!context || !context->update || !pointerPosition)
1683
0
    return FALSE;
1684
1685
0
  wParam = copy_pointer_position_update(context, pointerPosition);
1686
1687
0
  if (!wParam)
1688
0
    return FALSE;
1689
1690
0
  up = update_cast(context->update);
1691
0
  return MessageQueue_Post(up->queue, (void*)context,
1692
0
                           MakeMessageId(PointerUpdate, PointerPosition), (void*)wParam, nullptr);
1693
0
}
1694
1695
static BOOL update_message_PointerSystem(rdpContext* context,
1696
                                         const POINTER_SYSTEM_UPDATE* pointerSystem)
1697
0
{
1698
0
  POINTER_SYSTEM_UPDATE* wParam = nullptr;
1699
0
  rdp_update_internal* up = nullptr;
1700
1701
0
  if (!context || !context->update || !pointerSystem)
1702
0
    return FALSE;
1703
1704
0
  wParam = copy_pointer_system_update(context, pointerSystem);
1705
1706
0
  if (!wParam)
1707
0
    return FALSE;
1708
1709
0
  up = update_cast(context->update);
1710
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PointerUpdate, PointerSystem),
1711
0
                           (void*)wParam, nullptr);
1712
0
}
1713
1714
static BOOL update_message_PointerColor(rdpContext* context,
1715
                                        const POINTER_COLOR_UPDATE* pointerColor)
1716
0
{
1717
0
  POINTER_COLOR_UPDATE* wParam = nullptr;
1718
0
  rdp_update_internal* up = nullptr;
1719
1720
0
  if (!context || !context->update || !pointerColor)
1721
0
    return FALSE;
1722
1723
0
  wParam = copy_pointer_color_update(context, pointerColor);
1724
1725
0
  if (!wParam)
1726
0
    return FALSE;
1727
1728
0
  up = update_cast(context->update);
1729
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PointerUpdate, PointerColor),
1730
0
                           (void*)wParam, nullptr);
1731
0
}
1732
1733
static BOOL update_message_PointerLarge(rdpContext* context, const POINTER_LARGE_UPDATE* pointer)
1734
0
{
1735
0
  POINTER_LARGE_UPDATE* wParam = nullptr;
1736
0
  rdp_update_internal* up = nullptr;
1737
1738
0
  if (!context || !context->update || !pointer)
1739
0
    return FALSE;
1740
1741
0
  wParam = copy_pointer_large_update(context, pointer);
1742
1743
0
  if (!wParam)
1744
0
    return FALSE;
1745
1746
0
  up = update_cast(context->update);
1747
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PointerUpdate, PointerLarge),
1748
0
                           (void*)wParam, nullptr);
1749
0
}
1750
1751
static BOOL update_message_PointerNew(rdpContext* context, const POINTER_NEW_UPDATE* pointerNew)
1752
0
{
1753
0
  POINTER_NEW_UPDATE* wParam = nullptr;
1754
0
  rdp_update_internal* up = nullptr;
1755
1756
0
  if (!context || !context->update || !pointerNew)
1757
0
    return FALSE;
1758
1759
0
  wParam = copy_pointer_new_update(context, pointerNew);
1760
1761
0
  if (!wParam)
1762
0
    return FALSE;
1763
1764
0
  up = update_cast(context->update);
1765
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PointerUpdate, PointerNew),
1766
0
                           (void*)wParam, nullptr);
1767
0
}
1768
1769
static BOOL update_message_PointerCached(rdpContext* context,
1770
                                         const POINTER_CACHED_UPDATE* pointerCached)
1771
0
{
1772
0
  POINTER_CACHED_UPDATE* wParam = nullptr;
1773
0
  rdp_update_internal* up = nullptr;
1774
1775
0
  if (!context || !context->update || !pointerCached)
1776
0
    return FALSE;
1777
1778
0
  wParam = copy_pointer_cached_update(context, pointerCached);
1779
1780
0
  if (!wParam)
1781
0
    return FALSE;
1782
1783
0
  up = update_cast(context->update);
1784
0
  return MessageQueue_Post(up->queue, (void*)context, MakeMessageId(PointerUpdate, PointerCached),
1785
0
                           (void*)wParam, nullptr);
1786
0
}
1787
1788
/* Message Queue */
1789
static BOOL update_message_free_update_class(wMessage* msg, int type)
1790
0
{
1791
0
  rdpContext* context = nullptr;
1792
1793
0
  if (!msg)
1794
0
    return FALSE;
1795
1796
0
  context = (rdpContext*)msg->context;
1797
1798
0
  switch (type)
1799
0
  {
1800
0
    case Update_BeginPaint:
1801
0
      break;
1802
1803
0
    case Update_EndPaint:
1804
0
      break;
1805
1806
0
    case Update_SetBounds:
1807
0
      free(msg->wParam);
1808
0
      break;
1809
1810
0
    case Update_Synchronize:
1811
0
      break;
1812
1813
0
    case Update_DesktopResize:
1814
0
      break;
1815
1816
0
    case Update_BitmapUpdate:
1817
0
    {
1818
0
      BITMAP_UPDATE* wParam = (BITMAP_UPDATE*)msg->wParam;
1819
0
      free_bitmap_update(context, wParam);
1820
0
    }
1821
0
    break;
1822
1823
0
    case Update_Palette:
1824
0
    {
1825
0
      PALETTE_UPDATE* palette = (PALETTE_UPDATE*)msg->wParam;
1826
0
      free_palette_update(context, palette);
1827
0
    }
1828
0
    break;
1829
1830
0
    case Update_PlaySound:
1831
0
      free(msg->wParam);
1832
0
      break;
1833
1834
0
    case Update_RefreshRect:
1835
0
      free(msg->lParam);
1836
0
      break;
1837
1838
0
    case Update_SuppressOutput:
1839
0
      free(msg->lParam);
1840
0
      break;
1841
1842
0
    case Update_SurfaceCommand:
1843
0
    {
1844
0
      wStream* s = (wStream*)msg->wParam;
1845
0
      Stream_Free(s, TRUE);
1846
0
    }
1847
0
    break;
1848
1849
0
    case Update_SurfaceBits:
1850
0
    {
1851
0
      SURFACE_BITS_COMMAND* wParam = (SURFACE_BITS_COMMAND*)msg->wParam;
1852
0
      free_surface_bits_command(context, wParam);
1853
0
    }
1854
0
    break;
1855
1856
0
    case Update_SurfaceFrameMarker:
1857
0
      free(msg->wParam);
1858
0
      break;
1859
1860
0
    case Update_SurfaceFrameAcknowledge:
1861
0
    case Update_SetKeyboardIndicators:
1862
0
    case Update_SetKeyboardImeStatus:
1863
0
      break;
1864
1865
0
    default:
1866
0
      return FALSE;
1867
0
  }
1868
1869
0
  return TRUE;
1870
0
}
1871
1872
static BOOL update_message_process_update_class(rdpUpdateProxy* proxy, wMessage* msg, int type)
1873
0
{
1874
0
  BOOL rc = FALSE;
1875
1876
0
  if (!proxy || !msg)
1877
0
    return FALSE;
1878
1879
0
  switch (type)
1880
0
  {
1881
0
    case Update_BeginPaint:
1882
0
      rc = IFCALLRESULT(TRUE, proxy->BeginPaint, msg->context);
1883
0
      break;
1884
1885
0
    case Update_EndPaint:
1886
0
      rc = IFCALLRESULT(TRUE, proxy->EndPaint, msg->context);
1887
0
      break;
1888
1889
0
    case Update_SetBounds:
1890
0
      rc = IFCALLRESULT(TRUE, proxy->SetBounds, msg->context, (rdpBounds*)msg->wParam);
1891
0
      break;
1892
1893
0
    case Update_Synchronize:
1894
0
      rc = IFCALLRESULT(TRUE, proxy->Synchronize, msg->context);
1895
0
      break;
1896
1897
0
    case Update_DesktopResize:
1898
0
      rc = IFCALLRESULT(TRUE, proxy->DesktopResize, msg->context);
1899
0
      break;
1900
1901
0
    case Update_BitmapUpdate:
1902
0
      rc = IFCALLRESULT(TRUE, proxy->BitmapUpdate, msg->context, (BITMAP_UPDATE*)msg->wParam);
1903
0
      break;
1904
1905
0
    case Update_Palette:
1906
0
      rc = IFCALLRESULT(TRUE, proxy->Palette, msg->context, (PALETTE_UPDATE*)msg->wParam);
1907
0
      break;
1908
1909
0
    case Update_PlaySound:
1910
0
      rc =
1911
0
          IFCALLRESULT(TRUE, proxy->PlaySound, msg->context, (PLAY_SOUND_UPDATE*)msg->wParam);
1912
0
      break;
1913
1914
0
    case Update_RefreshRect:
1915
0
      rc = IFCALLRESULT(TRUE, proxy->RefreshRect, msg->context, (BYTE)(size_t)msg->wParam,
1916
0
                        (RECTANGLE_16*)msg->lParam);
1917
0
      break;
1918
1919
0
    case Update_SuppressOutput:
1920
0
      rc = IFCALLRESULT(TRUE, proxy->SuppressOutput, msg->context, (BYTE)(size_t)msg->wParam,
1921
0
                        (RECTANGLE_16*)msg->lParam);
1922
0
      break;
1923
1924
0
    case Update_SurfaceCommand:
1925
0
      rc = IFCALLRESULT(TRUE, proxy->SurfaceCommand, msg->context, (wStream*)msg->wParam);
1926
0
      break;
1927
1928
0
    case Update_SurfaceBits:
1929
0
      rc = IFCALLRESULT(TRUE, proxy->SurfaceBits, msg->context,
1930
0
                        (SURFACE_BITS_COMMAND*)msg->wParam);
1931
0
      break;
1932
1933
0
    case Update_SurfaceFrameMarker:
1934
0
      rc = IFCALLRESULT(TRUE, proxy->SurfaceFrameMarker, msg->context,
1935
0
                        (SURFACE_FRAME_MARKER*)msg->wParam);
1936
0
      break;
1937
1938
0
    case Update_SurfaceFrameAcknowledge:
1939
0
      rc = IFCALLRESULT(TRUE, proxy->SurfaceFrameAcknowledge, msg->context,
1940
0
                        (UINT32)(size_t)msg->wParam);
1941
0
      break;
1942
1943
0
    case Update_SetKeyboardIndicators:
1944
0
      rc = IFCALLRESULT(TRUE, proxy->SetKeyboardIndicators, msg->context,
1945
0
                        (UINT16)(size_t)msg->wParam);
1946
0
      break;
1947
1948
0
    case Update_SetKeyboardImeStatus:
1949
0
    {
1950
0
      const UINT16 imeId = ((size_t)msg->wParam) >> 16 & 0xFFFF;
1951
0
      const UINT32 imeState = ((size_t)msg->wParam) & 0xFFFF;
1952
0
      const UINT32 imeConvMode = ((size_t)msg->lParam) & 0xFFFFFFFFUL;
1953
0
      rc = IFCALLRESULT(TRUE, proxy->SetKeyboardImeStatus, msg->context, imeId, imeState,
1954
0
                        imeConvMode);
1955
0
    }
1956
0
    break;
1957
1958
0
    default:
1959
0
      break;
1960
0
  }
1961
1962
0
  return rc;
1963
0
}
1964
1965
static BOOL update_message_free_primary_update_class(wMessage* msg, int type)
1966
0
{
1967
0
  if (!msg)
1968
0
    return FALSE;
1969
1970
0
  switch (type)
1971
0
  {
1972
0
    case PrimaryUpdate_DstBlt:
1973
0
      free(msg->wParam);
1974
0
      break;
1975
1976
0
    case PrimaryUpdate_PatBlt:
1977
0
      free(msg->wParam);
1978
0
      break;
1979
1980
0
    case PrimaryUpdate_ScrBlt:
1981
0
      free(msg->wParam);
1982
0
      break;
1983
1984
0
    case PrimaryUpdate_OpaqueRect:
1985
0
      free(msg->wParam);
1986
0
      break;
1987
1988
0
    case PrimaryUpdate_DrawNineGrid:
1989
0
      free(msg->wParam);
1990
0
      break;
1991
1992
0
    case PrimaryUpdate_MultiDstBlt:
1993
0
      free(msg->wParam);
1994
0
      break;
1995
1996
0
    case PrimaryUpdate_MultiPatBlt:
1997
0
      free(msg->wParam);
1998
0
      break;
1999
2000
0
    case PrimaryUpdate_MultiScrBlt:
2001
0
      free(msg->wParam);
2002
0
      break;
2003
2004
0
    case PrimaryUpdate_MultiOpaqueRect:
2005
0
      free(msg->wParam);
2006
0
      break;
2007
2008
0
    case PrimaryUpdate_MultiDrawNineGrid:
2009
0
      free(msg->wParam);
2010
0
      break;
2011
2012
0
    case PrimaryUpdate_LineTo:
2013
0
      free(msg->wParam);
2014
0
      break;
2015
2016
0
    case PrimaryUpdate_Polyline:
2017
0
    {
2018
0
      POLYLINE_ORDER* wParam = (POLYLINE_ORDER*)msg->wParam;
2019
0
      free(wParam->points);
2020
0
      free(wParam);
2021
0
    }
2022
0
    break;
2023
2024
0
    case PrimaryUpdate_MemBlt:
2025
0
      free(msg->wParam);
2026
0
      break;
2027
2028
0
    case PrimaryUpdate_Mem3Blt:
2029
0
      free(msg->wParam);
2030
0
      break;
2031
2032
0
    case PrimaryUpdate_SaveBitmap:
2033
0
      free(msg->wParam);
2034
0
      break;
2035
2036
0
    case PrimaryUpdate_GlyphIndex:
2037
0
      free(msg->wParam);
2038
0
      break;
2039
2040
0
    case PrimaryUpdate_FastIndex:
2041
0
      free(msg->wParam);
2042
0
      break;
2043
2044
0
    case PrimaryUpdate_FastGlyph:
2045
0
    {
2046
0
      FAST_GLYPH_ORDER* wParam = (FAST_GLYPH_ORDER*)msg->wParam;
2047
0
      free(wParam->glyphData.aj);
2048
0
      free(wParam);
2049
0
    }
2050
0
    break;
2051
2052
0
    case PrimaryUpdate_PolygonSC:
2053
0
    {
2054
0
      POLYGON_SC_ORDER* wParam = (POLYGON_SC_ORDER*)msg->wParam;
2055
0
      free(wParam->points);
2056
0
      free(wParam);
2057
0
    }
2058
0
    break;
2059
2060
0
    case PrimaryUpdate_PolygonCB:
2061
0
    {
2062
0
      POLYGON_CB_ORDER* wParam = (POLYGON_CB_ORDER*)msg->wParam;
2063
0
      free(wParam->points);
2064
0
      free(wParam);
2065
0
    }
2066
0
    break;
2067
2068
0
    case PrimaryUpdate_EllipseSC:
2069
0
      free(msg->wParam);
2070
0
      break;
2071
2072
0
    case PrimaryUpdate_EllipseCB:
2073
0
      free(msg->wParam);
2074
0
      break;
2075
2076
0
    default:
2077
0
      return FALSE;
2078
0
  }
2079
2080
0
  return TRUE;
2081
0
}
2082
2083
static BOOL update_message_process_primary_update_class(rdpUpdateProxy* proxy, wMessage* msg,
2084
                                                        int type)
2085
0
{
2086
0
  if (!proxy || !msg)
2087
0
    return FALSE;
2088
2089
0
  switch (type)
2090
0
  {
2091
0
    case PrimaryUpdate_DstBlt:
2092
0
      return IFCALLRESULT(TRUE, proxy->DstBlt, msg->context, (DSTBLT_ORDER*)msg->wParam);
2093
2094
0
    case PrimaryUpdate_PatBlt:
2095
0
      return IFCALLRESULT(TRUE, proxy->PatBlt, msg->context, (PATBLT_ORDER*)msg->wParam);
2096
2097
0
    case PrimaryUpdate_ScrBlt:
2098
0
      return IFCALLRESULT(TRUE, proxy->ScrBlt, msg->context, (SCRBLT_ORDER*)msg->wParam);
2099
2100
0
    case PrimaryUpdate_OpaqueRect:
2101
0
      return IFCALLRESULT(TRUE, proxy->OpaqueRect, msg->context,
2102
0
                          (OPAQUE_RECT_ORDER*)msg->wParam);
2103
2104
0
    case PrimaryUpdate_DrawNineGrid:
2105
0
      return IFCALLRESULT(TRUE, proxy->DrawNineGrid, msg->context,
2106
0
                          (DRAW_NINE_GRID_ORDER*)msg->wParam);
2107
2108
0
    case PrimaryUpdate_MultiDstBlt:
2109
0
      return IFCALLRESULT(TRUE, proxy->MultiDstBlt, msg->context,
2110
0
                          (MULTI_DSTBLT_ORDER*)msg->wParam);
2111
2112
0
    case PrimaryUpdate_MultiPatBlt:
2113
0
      return IFCALLRESULT(TRUE, proxy->MultiPatBlt, msg->context,
2114
0
                          (MULTI_PATBLT_ORDER*)msg->wParam);
2115
2116
0
    case PrimaryUpdate_MultiScrBlt:
2117
0
      return IFCALLRESULT(TRUE, proxy->MultiScrBlt, msg->context,
2118
0
                          (MULTI_SCRBLT_ORDER*)msg->wParam);
2119
2120
0
    case PrimaryUpdate_MultiOpaqueRect:
2121
0
      return IFCALLRESULT(TRUE, proxy->MultiOpaqueRect, msg->context,
2122
0
                          (MULTI_OPAQUE_RECT_ORDER*)msg->wParam);
2123
2124
0
    case PrimaryUpdate_MultiDrawNineGrid:
2125
0
      return IFCALLRESULT(TRUE, proxy->MultiDrawNineGrid, msg->context,
2126
0
                          (MULTI_DRAW_NINE_GRID_ORDER*)msg->wParam);
2127
2128
0
    case PrimaryUpdate_LineTo:
2129
0
      return IFCALLRESULT(TRUE, proxy->LineTo, msg->context, (LINE_TO_ORDER*)msg->wParam);
2130
2131
0
    case PrimaryUpdate_Polyline:
2132
0
      return IFCALLRESULT(TRUE, proxy->Polyline, msg->context, (POLYLINE_ORDER*)msg->wParam);
2133
2134
0
    case PrimaryUpdate_MemBlt:
2135
0
      return IFCALLRESULT(TRUE, proxy->MemBlt, msg->context, (MEMBLT_ORDER*)msg->wParam);
2136
2137
0
    case PrimaryUpdate_Mem3Blt:
2138
0
      return IFCALLRESULT(TRUE, proxy->Mem3Blt, msg->context, (MEM3BLT_ORDER*)msg->wParam);
2139
2140
0
    case PrimaryUpdate_SaveBitmap:
2141
0
      return IFCALLRESULT(TRUE, proxy->SaveBitmap, msg->context,
2142
0
                          (SAVE_BITMAP_ORDER*)msg->wParam);
2143
2144
0
    case PrimaryUpdate_GlyphIndex:
2145
0
      return IFCALLRESULT(TRUE, proxy->GlyphIndex, msg->context,
2146
0
                          (GLYPH_INDEX_ORDER*)msg->wParam);
2147
2148
0
    case PrimaryUpdate_FastIndex:
2149
0
      return IFCALLRESULT(TRUE, proxy->FastIndex, msg->context,
2150
0
                          (FAST_INDEX_ORDER*)msg->wParam);
2151
2152
0
    case PrimaryUpdate_FastGlyph:
2153
0
      return IFCALLRESULT(TRUE, proxy->FastGlyph, msg->context,
2154
0
                          (FAST_GLYPH_ORDER*)msg->wParam);
2155
2156
0
    case PrimaryUpdate_PolygonSC:
2157
0
      return IFCALLRESULT(TRUE, proxy->PolygonSC, msg->context,
2158
0
                          (POLYGON_SC_ORDER*)msg->wParam);
2159
2160
0
    case PrimaryUpdate_PolygonCB:
2161
0
      return IFCALLRESULT(TRUE, proxy->PolygonCB, msg->context,
2162
0
                          (POLYGON_CB_ORDER*)msg->wParam);
2163
2164
0
    case PrimaryUpdate_EllipseSC:
2165
0
      return IFCALLRESULT(TRUE, proxy->EllipseSC, msg->context,
2166
0
                          (ELLIPSE_SC_ORDER*)msg->wParam);
2167
2168
0
    case PrimaryUpdate_EllipseCB:
2169
0
      return IFCALLRESULT(TRUE, proxy->EllipseCB, msg->context,
2170
0
                          (ELLIPSE_CB_ORDER*)msg->wParam);
2171
2172
0
    default:
2173
0
      return FALSE;
2174
0
  }
2175
0
}
2176
2177
static BOOL update_message_free_secondary_update_class(wMessage* msg, int type)
2178
0
{
2179
0
  rdpContext* context = nullptr;
2180
2181
0
  if (!msg)
2182
0
    return FALSE;
2183
2184
0
  context = msg->context;
2185
2186
0
  switch (type)
2187
0
  {
2188
0
    case SecondaryUpdate_CacheBitmap:
2189
0
    {
2190
0
      CACHE_BITMAP_ORDER* wParam = (CACHE_BITMAP_ORDER*)msg->wParam;
2191
0
      free_cache_bitmap_order(context, wParam);
2192
0
    }
2193
0
    break;
2194
2195
0
    case SecondaryUpdate_CacheBitmapV2:
2196
0
    {
2197
0
      CACHE_BITMAP_V2_ORDER* wParam = (CACHE_BITMAP_V2_ORDER*)msg->wParam;
2198
0
      free_cache_bitmap_v2_order(context, wParam);
2199
0
    }
2200
0
    break;
2201
2202
0
    case SecondaryUpdate_CacheBitmapV3:
2203
0
    {
2204
0
      CACHE_BITMAP_V3_ORDER* wParam = (CACHE_BITMAP_V3_ORDER*)msg->wParam;
2205
0
      free_cache_bitmap_v3_order(context, wParam);
2206
0
    }
2207
0
    break;
2208
2209
0
    case SecondaryUpdate_CacheColorTable:
2210
0
    {
2211
0
      CACHE_COLOR_TABLE_ORDER* wParam = (CACHE_COLOR_TABLE_ORDER*)msg->wParam;
2212
0
      free_cache_color_table_order(context, wParam);
2213
0
    }
2214
0
    break;
2215
2216
0
    case SecondaryUpdate_CacheGlyph:
2217
0
    {
2218
0
      CACHE_GLYPH_ORDER* wParam = (CACHE_GLYPH_ORDER*)msg->wParam;
2219
0
      free_cache_glyph_order(context, wParam);
2220
0
    }
2221
0
    break;
2222
2223
0
    case SecondaryUpdate_CacheGlyphV2:
2224
0
    {
2225
0
      CACHE_GLYPH_V2_ORDER* wParam = (CACHE_GLYPH_V2_ORDER*)msg->wParam;
2226
0
      free_cache_glyph_v2_order(context, wParam);
2227
0
    }
2228
0
    break;
2229
2230
0
    case SecondaryUpdate_CacheBrush:
2231
0
    {
2232
0
      CACHE_BRUSH_ORDER* wParam = (CACHE_BRUSH_ORDER*)msg->wParam;
2233
0
      free_cache_brush_order(context, wParam);
2234
0
    }
2235
0
    break;
2236
2237
0
    default:
2238
0
      return FALSE;
2239
0
  }
2240
2241
0
  return TRUE;
2242
0
}
2243
2244
static BOOL update_message_process_secondary_update_class(rdpUpdateProxy* proxy, wMessage* msg,
2245
                                                          int type)
2246
0
{
2247
0
  if (!proxy || !msg)
2248
0
    return FALSE;
2249
2250
0
  switch (type)
2251
0
  {
2252
0
    case SecondaryUpdate_CacheBitmap:
2253
0
      return IFCALLRESULT(TRUE, proxy->CacheBitmap, msg->context,
2254
0
                          (CACHE_BITMAP_ORDER*)msg->wParam);
2255
2256
0
    case SecondaryUpdate_CacheBitmapV2:
2257
0
      return IFCALLRESULT(TRUE, proxy->CacheBitmapV2, msg->context,
2258
0
                          (CACHE_BITMAP_V2_ORDER*)msg->wParam);
2259
2260
0
    case SecondaryUpdate_CacheBitmapV3:
2261
0
      return IFCALLRESULT(TRUE, proxy->CacheBitmapV3, msg->context,
2262
0
                          (CACHE_BITMAP_V3_ORDER*)msg->wParam);
2263
2264
0
    case SecondaryUpdate_CacheColorTable:
2265
0
      return IFCALLRESULT(TRUE, proxy->CacheColorTable, msg->context,
2266
0
                          (CACHE_COLOR_TABLE_ORDER*)msg->wParam);
2267
2268
0
    case SecondaryUpdate_CacheGlyph:
2269
0
      return IFCALLRESULT(TRUE, proxy->CacheGlyph, msg->context,
2270
0
                          (CACHE_GLYPH_ORDER*)msg->wParam);
2271
2272
0
    case SecondaryUpdate_CacheGlyphV2:
2273
0
      return IFCALLRESULT(TRUE, proxy->CacheGlyphV2, msg->context,
2274
0
                          (CACHE_GLYPH_V2_ORDER*)msg->wParam);
2275
2276
0
    case SecondaryUpdate_CacheBrush:
2277
0
      return IFCALLRESULT(TRUE, proxy->CacheBrush, msg->context,
2278
0
                          (CACHE_BRUSH_ORDER*)msg->wParam);
2279
2280
0
    default:
2281
0
      return FALSE;
2282
0
  }
2283
0
}
2284
2285
static BOOL update_message_free_altsec_update_class(wMessage* msg, int type)
2286
0
{
2287
0
  if (!msg)
2288
0
    return FALSE;
2289
2290
0
  switch (type)
2291
0
  {
2292
0
    case AltSecUpdate_CreateOffscreenBitmap:
2293
0
    {
2294
0
      CREATE_OFFSCREEN_BITMAP_ORDER* wParam = (CREATE_OFFSCREEN_BITMAP_ORDER*)msg->wParam;
2295
0
      free(wParam->deleteList.indices);
2296
0
      free(wParam);
2297
0
    }
2298
0
    break;
2299
2300
0
    case AltSecUpdate_SwitchSurface:
2301
0
      free(msg->wParam);
2302
0
      break;
2303
2304
0
    case AltSecUpdate_CreateNineGridBitmap:
2305
0
      free(msg->wParam);
2306
0
      break;
2307
2308
0
    case AltSecUpdate_FrameMarker:
2309
0
      free(msg->wParam);
2310
0
      break;
2311
2312
0
    case AltSecUpdate_StreamBitmapFirst:
2313
0
      free(msg->wParam);
2314
0
      break;
2315
2316
0
    case AltSecUpdate_StreamBitmapNext:
2317
0
      free(msg->wParam);
2318
0
      break;
2319
2320
0
    case AltSecUpdate_DrawGdiPlusFirst:
2321
0
      free(msg->wParam);
2322
0
      break;
2323
2324
0
    case AltSecUpdate_DrawGdiPlusNext:
2325
0
      free(msg->wParam);
2326
0
      break;
2327
2328
0
    case AltSecUpdate_DrawGdiPlusEnd:
2329
0
      free(msg->wParam);
2330
0
      break;
2331
2332
0
    case AltSecUpdate_DrawGdiPlusCacheFirst:
2333
0
      free(msg->wParam);
2334
0
      break;
2335
2336
0
    case AltSecUpdate_DrawGdiPlusCacheNext:
2337
0
      free(msg->wParam);
2338
0
      break;
2339
2340
0
    case AltSecUpdate_DrawGdiPlusCacheEnd:
2341
0
      free(msg->wParam);
2342
0
      break;
2343
2344
0
    default:
2345
0
      return FALSE;
2346
0
  }
2347
2348
0
  return TRUE;
2349
0
}
2350
2351
static BOOL update_message_process_altsec_update_class(rdpUpdateProxy* proxy, wMessage* msg,
2352
                                                       int type)
2353
0
{
2354
0
  if (!proxy || !msg)
2355
0
    return FALSE;
2356
2357
0
  switch (type)
2358
0
  {
2359
0
    case AltSecUpdate_CreateOffscreenBitmap:
2360
0
      return IFCALLRESULT(TRUE, proxy->CreateOffscreenBitmap, msg->context,
2361
0
                          (CREATE_OFFSCREEN_BITMAP_ORDER*)msg->wParam);
2362
2363
0
    case AltSecUpdate_SwitchSurface:
2364
0
      return IFCALLRESULT(TRUE, proxy->SwitchSurface, msg->context,
2365
0
                          (SWITCH_SURFACE_ORDER*)msg->wParam);
2366
2367
0
    case AltSecUpdate_CreateNineGridBitmap:
2368
0
      return IFCALLRESULT(TRUE, proxy->CreateNineGridBitmap, msg->context,
2369
0
                          (CREATE_NINE_GRID_BITMAP_ORDER*)msg->wParam);
2370
2371
0
    case AltSecUpdate_FrameMarker:
2372
0
      return IFCALLRESULT(TRUE, proxy->FrameMarker, msg->context,
2373
0
                          (FRAME_MARKER_ORDER*)msg->wParam);
2374
2375
0
    case AltSecUpdate_StreamBitmapFirst:
2376
0
      return IFCALLRESULT(TRUE, proxy->StreamBitmapFirst, msg->context,
2377
0
                          (STREAM_BITMAP_FIRST_ORDER*)msg->wParam);
2378
2379
0
    case AltSecUpdate_StreamBitmapNext:
2380
0
      return IFCALLRESULT(TRUE, proxy->StreamBitmapNext, msg->context,
2381
0
                          (STREAM_BITMAP_NEXT_ORDER*)msg->wParam);
2382
2383
0
    case AltSecUpdate_DrawGdiPlusFirst:
2384
0
      return IFCALLRESULT(TRUE, proxy->DrawGdiPlusFirst, msg->context,
2385
0
                          (DRAW_GDIPLUS_FIRST_ORDER*)msg->wParam);
2386
2387
0
    case AltSecUpdate_DrawGdiPlusNext:
2388
0
      return IFCALLRESULT(TRUE, proxy->DrawGdiPlusNext, msg->context,
2389
0
                          (DRAW_GDIPLUS_NEXT_ORDER*)msg->wParam);
2390
2391
0
    case AltSecUpdate_DrawGdiPlusEnd:
2392
0
      return IFCALLRESULT(TRUE, proxy->DrawGdiPlusEnd, msg->context,
2393
0
                          (DRAW_GDIPLUS_END_ORDER*)msg->wParam);
2394
2395
0
    case AltSecUpdate_DrawGdiPlusCacheFirst:
2396
0
      return IFCALLRESULT(TRUE, proxy->DrawGdiPlusCacheFirst, msg->context,
2397
0
                          (DRAW_GDIPLUS_CACHE_FIRST_ORDER*)msg->wParam);
2398
2399
0
    case AltSecUpdate_DrawGdiPlusCacheNext:
2400
0
      return IFCALLRESULT(TRUE, proxy->DrawGdiPlusCacheNext, msg->context,
2401
0
                          (DRAW_GDIPLUS_CACHE_NEXT_ORDER*)msg->wParam);
2402
2403
0
    case AltSecUpdate_DrawGdiPlusCacheEnd:
2404
0
      return IFCALLRESULT(TRUE, proxy->DrawGdiPlusCacheEnd, msg->context,
2405
0
                          (DRAW_GDIPLUS_CACHE_END_ORDER*)msg->wParam);
2406
2407
0
    default:
2408
0
      return FALSE;
2409
0
  }
2410
0
}
2411
2412
static BOOL update_message_free_window_update_class(wMessage* msg, int type)
2413
0
{
2414
0
  if (!msg)
2415
0
    return FALSE;
2416
2417
0
  switch (type)
2418
0
  {
2419
0
    case WindowUpdate_WindowCreate:
2420
0
      free(msg->wParam);
2421
0
      window_state_order_free(msg->lParam);
2422
0
      break;
2423
2424
0
    case WindowUpdate_WindowUpdate:
2425
0
      free(msg->wParam);
2426
0
      window_state_order_free(msg->lParam);
2427
0
      break;
2428
2429
0
    case WindowUpdate_WindowIcon:
2430
0
    {
2431
0
      WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*)msg->wParam;
2432
0
      WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*)msg->lParam;
2433
2434
0
      if (windowIcon->iconInfo->cbBitsColor > 0)
2435
0
      {
2436
0
        free(windowIcon->iconInfo->bitsColor);
2437
0
      }
2438
2439
0
      if (windowIcon->iconInfo->cbBitsMask > 0)
2440
0
      {
2441
0
        free(windowIcon->iconInfo->bitsMask);
2442
0
      }
2443
2444
0
      if (windowIcon->iconInfo->cbColorTable > 0)
2445
0
      {
2446
0
        free(windowIcon->iconInfo->colorTable);
2447
0
      }
2448
2449
0
      free(orderInfo);
2450
0
      free(windowIcon->iconInfo);
2451
0
      free(windowIcon);
2452
0
    }
2453
0
    break;
2454
2455
0
    case WindowUpdate_WindowCachedIcon:
2456
0
      free(msg->wParam);
2457
0
      free(msg->lParam);
2458
0
      break;
2459
2460
0
    case WindowUpdate_WindowDelete:
2461
0
      free(msg->wParam);
2462
0
      break;
2463
2464
0
    case WindowUpdate_NotifyIconCreate:
2465
0
      free(msg->wParam);
2466
0
      notify_icon_state_order_free(msg->lParam);
2467
0
      break;
2468
2469
0
    case WindowUpdate_NotifyIconUpdate:
2470
0
      free(msg->wParam);
2471
0
      notify_icon_state_order_free(msg->lParam);
2472
0
      break;
2473
2474
0
    case WindowUpdate_NotifyIconDelete:
2475
0
      free(msg->wParam);
2476
0
      break;
2477
2478
0
    case WindowUpdate_MonitoredDesktop:
2479
0
    {
2480
0
      MONITORED_DESKTOP_ORDER* lParam = (MONITORED_DESKTOP_ORDER*)msg->lParam;
2481
0
      free(msg->wParam);
2482
0
      free(lParam->windowIds);
2483
0
      free(lParam);
2484
0
    }
2485
0
    break;
2486
2487
0
    case WindowUpdate_NonMonitoredDesktop:
2488
0
      free(msg->wParam);
2489
0
      break;
2490
2491
0
    default:
2492
0
      return FALSE;
2493
0
  }
2494
2495
0
  return TRUE;
2496
0
}
2497
2498
static BOOL update_message_process_window_update_class(rdpUpdateProxy* proxy, wMessage* msg,
2499
                                                       int type)
2500
0
{
2501
0
  if (!proxy || !msg)
2502
0
    return FALSE;
2503
2504
0
  switch (type)
2505
0
  {
2506
0
    case WindowUpdate_WindowCreate:
2507
0
      return IFCALLRESULT(TRUE, proxy->WindowCreate, msg->context,
2508
0
                          (WINDOW_ORDER_INFO*)msg->wParam, (WINDOW_STATE_ORDER*)msg->lParam);
2509
2510
0
    case WindowUpdate_WindowUpdate:
2511
0
      return IFCALLRESULT(TRUE, proxy->WindowCreate, msg->context,
2512
0
                          (WINDOW_ORDER_INFO*)msg->wParam, (WINDOW_STATE_ORDER*)msg->lParam);
2513
2514
0
    case WindowUpdate_WindowIcon:
2515
0
    {
2516
0
      WINDOW_ORDER_INFO* orderInfo = (WINDOW_ORDER_INFO*)msg->wParam;
2517
0
      WINDOW_ICON_ORDER* windowIcon = (WINDOW_ICON_ORDER*)msg->lParam;
2518
0
      return IFCALLRESULT(TRUE, proxy->WindowIcon, msg->context, orderInfo, windowIcon);
2519
0
    }
2520
2521
0
    case WindowUpdate_WindowCachedIcon:
2522
0
      return IFCALLRESULT(TRUE, proxy->WindowCachedIcon, msg->context,
2523
0
                          (WINDOW_ORDER_INFO*)msg->wParam,
2524
0
                          (WINDOW_CACHED_ICON_ORDER*)msg->lParam);
2525
2526
0
    case WindowUpdate_WindowDelete:
2527
0
      return IFCALLRESULT(TRUE, proxy->WindowDelete, msg->context,
2528
0
                          (WINDOW_ORDER_INFO*)msg->wParam);
2529
2530
0
    case WindowUpdate_NotifyIconCreate:
2531
0
      return IFCALLRESULT(TRUE, proxy->NotifyIconCreate, msg->context,
2532
0
                          (WINDOW_ORDER_INFO*)msg->wParam,
2533
0
                          (NOTIFY_ICON_STATE_ORDER*)msg->lParam);
2534
2535
0
    case WindowUpdate_NotifyIconUpdate:
2536
0
      return IFCALLRESULT(TRUE, proxy->NotifyIconUpdate, msg->context,
2537
0
                          (WINDOW_ORDER_INFO*)msg->wParam,
2538
0
                          (NOTIFY_ICON_STATE_ORDER*)msg->lParam);
2539
2540
0
    case WindowUpdate_NotifyIconDelete:
2541
0
      return IFCALLRESULT(TRUE, proxy->NotifyIconDelete, msg->context,
2542
0
                          (WINDOW_ORDER_INFO*)msg->wParam);
2543
2544
0
    case WindowUpdate_MonitoredDesktop:
2545
0
      return IFCALLRESULT(TRUE, proxy->MonitoredDesktop, msg->context,
2546
0
                          (WINDOW_ORDER_INFO*)msg->wParam,
2547
0
                          (MONITORED_DESKTOP_ORDER*)msg->lParam);
2548
2549
0
    case WindowUpdate_NonMonitoredDesktop:
2550
0
      return IFCALLRESULT(TRUE, proxy->NonMonitoredDesktop, msg->context,
2551
0
                          (WINDOW_ORDER_INFO*)msg->wParam);
2552
2553
0
    default:
2554
0
      return FALSE;
2555
0
  }
2556
0
}
2557
2558
static BOOL update_message_free_pointer_update_class(wMessage* msg, int type)
2559
0
{
2560
0
  rdpContext* context = nullptr;
2561
2562
0
  if (!msg)
2563
0
    return FALSE;
2564
2565
0
  context = msg->context;
2566
2567
0
  switch (type)
2568
0
  {
2569
0
    case PointerUpdate_PointerPosition:
2570
0
    {
2571
0
      POINTER_POSITION_UPDATE* wParam = (POINTER_POSITION_UPDATE*)msg->wParam;
2572
0
      free_pointer_position_update(context, wParam);
2573
0
    }
2574
0
    break;
2575
2576
0
    case PointerUpdate_PointerSystem:
2577
0
    {
2578
0
      POINTER_SYSTEM_UPDATE* wParam = (POINTER_SYSTEM_UPDATE*)msg->wParam;
2579
0
      free_pointer_system_update(context, wParam);
2580
0
    }
2581
0
    break;
2582
2583
0
    case PointerUpdate_PointerCached:
2584
0
    {
2585
0
      POINTER_CACHED_UPDATE* wParam = (POINTER_CACHED_UPDATE*)msg->wParam;
2586
0
      free_pointer_cached_update(context, wParam);
2587
0
    }
2588
0
    break;
2589
2590
0
    case PointerUpdate_PointerColor:
2591
0
    {
2592
0
      POINTER_COLOR_UPDATE* wParam = (POINTER_COLOR_UPDATE*)msg->wParam;
2593
0
      free_pointer_color_update(context, wParam);
2594
0
    }
2595
0
    break;
2596
2597
0
    case PointerUpdate_PointerNew:
2598
0
    {
2599
0
      POINTER_NEW_UPDATE* wParam = (POINTER_NEW_UPDATE*)msg->wParam;
2600
0
      free_pointer_new_update(context, wParam);
2601
0
    }
2602
0
    break;
2603
2604
0
    default:
2605
0
      return FALSE;
2606
0
  }
2607
2608
0
  return TRUE;
2609
0
}
2610
2611
static BOOL update_message_process_pointer_update_class(rdpUpdateProxy* proxy, wMessage* msg,
2612
                                                        int type)
2613
0
{
2614
0
  if (!proxy || !msg)
2615
0
    return FALSE;
2616
2617
0
  switch (type)
2618
0
  {
2619
0
    case PointerUpdate_PointerPosition:
2620
0
      return IFCALLRESULT(TRUE, proxy->PointerPosition, msg->context,
2621
0
                          (POINTER_POSITION_UPDATE*)msg->wParam);
2622
2623
0
    case PointerUpdate_PointerSystem:
2624
0
      return IFCALLRESULT(TRUE, proxy->PointerSystem, msg->context,
2625
0
                          (POINTER_SYSTEM_UPDATE*)msg->wParam);
2626
2627
0
    case PointerUpdate_PointerColor:
2628
0
      return IFCALLRESULT(TRUE, proxy->PointerColor, msg->context,
2629
0
                          (POINTER_COLOR_UPDATE*)msg->wParam);
2630
2631
0
    case PointerUpdate_PointerNew:
2632
0
      return IFCALLRESULT(TRUE, proxy->PointerNew, msg->context,
2633
0
                          (POINTER_NEW_UPDATE*)msg->wParam);
2634
2635
0
    case PointerUpdate_PointerCached:
2636
0
      return IFCALLRESULT(TRUE, proxy->PointerCached, msg->context,
2637
0
                          (POINTER_CACHED_UPDATE*)msg->wParam);
2638
2639
0
    default:
2640
0
      return FALSE;
2641
0
  }
2642
0
}
2643
2644
static BOOL update_message_free_class(wMessage* msg, int msgClass, int msgType)
2645
0
{
2646
0
  BOOL status = FALSE;
2647
2648
0
  switch (msgClass)
2649
0
  {
2650
0
    case Update_Class:
2651
0
      status = update_message_free_update_class(msg, msgType);
2652
0
      break;
2653
2654
0
    case PrimaryUpdate_Class:
2655
0
      status = update_message_free_primary_update_class(msg, msgType);
2656
0
      break;
2657
2658
0
    case SecondaryUpdate_Class:
2659
0
      status = update_message_free_secondary_update_class(msg, msgType);
2660
0
      break;
2661
2662
0
    case AltSecUpdate_Class:
2663
0
      status = update_message_free_altsec_update_class(msg, msgType);
2664
0
      break;
2665
2666
0
    case WindowUpdate_Class:
2667
0
      status = update_message_free_window_update_class(msg, msgType);
2668
0
      break;
2669
2670
0
    case PointerUpdate_Class:
2671
0
      status = update_message_free_pointer_update_class(msg, msgType);
2672
0
      break;
2673
2674
0
    default:
2675
0
      break;
2676
0
  }
2677
2678
0
  if (!status)
2679
0
    WLog_ERR(TAG, "Unknown message: class: %d type: %d", msgClass, msgType);
2680
2681
0
  return status;
2682
0
}
2683
2684
static int update_message_process_class(rdpUpdateProxy* proxy, wMessage* msg, int msgClass,
2685
                                        int msgType)
2686
0
{
2687
0
  BOOL status = FALSE;
2688
2689
0
  switch (msgClass)
2690
0
  {
2691
0
    case Update_Class:
2692
0
      status = update_message_process_update_class(proxy, msg, msgType);
2693
0
      break;
2694
2695
0
    case PrimaryUpdate_Class:
2696
0
      status = update_message_process_primary_update_class(proxy, msg, msgType);
2697
0
      break;
2698
2699
0
    case SecondaryUpdate_Class:
2700
0
      status = update_message_process_secondary_update_class(proxy, msg, msgType);
2701
0
      break;
2702
2703
0
    case AltSecUpdate_Class:
2704
0
      status = update_message_process_altsec_update_class(proxy, msg, msgType);
2705
0
      break;
2706
2707
0
    case WindowUpdate_Class:
2708
0
      status = update_message_process_window_update_class(proxy, msg, msgType);
2709
0
      break;
2710
2711
0
    case PointerUpdate_Class:
2712
0
      status = update_message_process_pointer_update_class(proxy, msg, msgType);
2713
0
      break;
2714
2715
0
    default:
2716
0
      status = FALSE;
2717
0
      break;
2718
0
  }
2719
2720
0
  if (!status)
2721
0
  {
2722
0
    WLog_ERR(TAG, "message: class: %d type: %d failed", msgClass, msgType);
2723
0
    return -1;
2724
0
  }
2725
2726
0
  return 0;
2727
0
}
2728
2729
int update_message_queue_process_message(rdpUpdate* update, wMessage* message)
2730
0
{
2731
0
  int status = 0;
2732
0
  int msgClass = 0;
2733
0
  int msgType = 0;
2734
0
  rdp_update_internal* up = update_cast(update);
2735
2736
0
  if (!update || !message)
2737
0
    return -1;
2738
2739
0
  if (message->id == WMQ_QUIT)
2740
0
    return 0;
2741
2742
0
  msgClass = GetMessageClass(message->id);
2743
0
  msgType = GetMessageType(message->id);
2744
0
  status = update_message_process_class(up->proxy, message, msgClass, msgType);
2745
0
  update_message_free_class(message, msgClass, msgType);
2746
2747
0
  if (status < 0)
2748
0
    return -1;
2749
2750
0
  return 1;
2751
0
}
2752
2753
int update_message_queue_free_message(wMessage* message)
2754
0
{
2755
0
  int msgClass = 0;
2756
0
  int msgType = 0;
2757
2758
0
  if (!message)
2759
0
    return -1;
2760
2761
0
  if (message->id == WMQ_QUIT)
2762
0
    return 0;
2763
2764
0
  msgClass = GetMessageClass(message->id);
2765
0
  msgType = GetMessageType(message->id);
2766
0
  return update_message_free_class(message, msgClass, msgType);
2767
0
}
2768
2769
int update_message_queue_process_pending_messages(rdpUpdate* update)
2770
0
{
2771
0
  int status = 1;
2772
0
  wMessage message = WINPR_C_ARRAY_INIT;
2773
0
  rdp_update_internal* up = update_cast(update);
2774
2775
0
  wMessageQueue* queue = up->queue;
2776
2777
0
  while (MessageQueue_Peek(queue, &message, TRUE))
2778
0
  {
2779
0
    status = update_message_queue_process_message(update, &message);
2780
2781
0
    if (!status)
2782
0
      break;
2783
0
  }
2784
2785
0
  return status;
2786
0
}
2787
2788
static BOOL update_message_register_interface(rdpUpdateProxy* message, rdpUpdate* update)
2789
0
{
2790
0
  rdpPrimaryUpdate* primary = nullptr;
2791
0
  rdpSecondaryUpdate* secondary = nullptr;
2792
0
  rdpAltSecUpdate* altsec = nullptr;
2793
0
  rdpWindowUpdate* window = nullptr;
2794
0
  rdpPointerUpdate* pointer = nullptr;
2795
2796
0
  if (!message || !update)
2797
0
    return FALSE;
2798
2799
0
  primary = update->primary;
2800
0
  secondary = update->secondary;
2801
0
  altsec = update->altsec;
2802
0
  window = update->window;
2803
0
  pointer = update->pointer;
2804
2805
0
  if (!primary || !secondary || !altsec || !window || !pointer)
2806
0
    return FALSE;
2807
2808
  /* Update */
2809
0
  message->BeginPaint = update->BeginPaint;
2810
0
  message->EndPaint = update->EndPaint;
2811
0
  message->SetBounds = update->SetBounds;
2812
0
  message->Synchronize = update->Synchronize;
2813
0
  message->DesktopResize = update->DesktopResize;
2814
0
  message->BitmapUpdate = update->BitmapUpdate;
2815
0
  message->Palette = update->Palette;
2816
0
  message->PlaySound = update->PlaySound;
2817
0
  message->SetKeyboardIndicators = update->SetKeyboardIndicators;
2818
0
  message->SetKeyboardImeStatus = update->SetKeyboardImeStatus;
2819
0
  message->RefreshRect = update->RefreshRect;
2820
0
  message->SuppressOutput = update->SuppressOutput;
2821
0
  message->SurfaceCommand = update->SurfaceCommand;
2822
0
  message->SurfaceBits = update->SurfaceBits;
2823
0
  message->SurfaceFrameMarker = update->SurfaceFrameMarker;
2824
0
  message->SurfaceFrameAcknowledge = update->SurfaceFrameAcknowledge;
2825
0
  update->BeginPaint = update_message_BeginPaint;
2826
0
  update->EndPaint = update_message_EndPaint;
2827
0
  update->SetBounds = update_message_SetBounds;
2828
0
  update->Synchronize = update_message_Synchronize;
2829
0
  update->DesktopResize = update_message_DesktopResize;
2830
0
  update->BitmapUpdate = update_message_BitmapUpdate;
2831
0
  update->Palette = update_message_Palette;
2832
0
  update->PlaySound = update_message_PlaySound;
2833
0
  update->SetKeyboardIndicators = update_message_SetKeyboardIndicators;
2834
0
  update->SetKeyboardImeStatus = update_message_SetKeyboardImeStatus;
2835
0
  update->RefreshRect = update_message_RefreshRect;
2836
0
  update->SuppressOutput = update_message_SuppressOutput;
2837
0
  update->SurfaceCommand = update_message_SurfaceCommand;
2838
0
  update->SurfaceBits = update_message_SurfaceBits;
2839
0
  update->SurfaceFrameMarker = update_message_SurfaceFrameMarker;
2840
0
  update->SurfaceFrameAcknowledge = update_message_SurfaceFrameAcknowledge;
2841
  /* Primary Update */
2842
0
  message->DstBlt = primary->DstBlt;
2843
0
  message->PatBlt = primary->PatBlt;
2844
0
  message->ScrBlt = primary->ScrBlt;
2845
0
  message->OpaqueRect = primary->OpaqueRect;
2846
0
  message->DrawNineGrid = primary->DrawNineGrid;
2847
0
  message->MultiDstBlt = primary->MultiDstBlt;
2848
0
  message->MultiPatBlt = primary->MultiPatBlt;
2849
0
  message->MultiScrBlt = primary->MultiScrBlt;
2850
0
  message->MultiOpaqueRect = primary->MultiOpaqueRect;
2851
0
  message->MultiDrawNineGrid = primary->MultiDrawNineGrid;
2852
0
  message->LineTo = primary->LineTo;
2853
0
  message->Polyline = primary->Polyline;
2854
0
  message->MemBlt = primary->MemBlt;
2855
0
  message->Mem3Blt = primary->Mem3Blt;
2856
0
  message->SaveBitmap = primary->SaveBitmap;
2857
0
  message->GlyphIndex = primary->GlyphIndex;
2858
0
  message->FastIndex = primary->FastIndex;
2859
0
  message->FastGlyph = primary->FastGlyph;
2860
0
  message->PolygonSC = primary->PolygonSC;
2861
0
  message->PolygonCB = primary->PolygonCB;
2862
0
  message->EllipseSC = primary->EllipseSC;
2863
0
  message->EllipseCB = primary->EllipseCB;
2864
0
  primary->DstBlt = update_message_DstBlt;
2865
0
  primary->PatBlt = update_message_PatBlt;
2866
0
  primary->ScrBlt = update_message_ScrBlt;
2867
0
  primary->OpaqueRect = update_message_OpaqueRect;
2868
0
  primary->DrawNineGrid = update_message_DrawNineGrid;
2869
0
  primary->MultiDstBlt = update_message_MultiDstBlt;
2870
0
  primary->MultiPatBlt = update_message_MultiPatBlt;
2871
0
  primary->MultiScrBlt = update_message_MultiScrBlt;
2872
0
  primary->MultiOpaqueRect = update_message_MultiOpaqueRect;
2873
0
  primary->MultiDrawNineGrid = update_message_MultiDrawNineGrid;
2874
0
  primary->LineTo = update_message_LineTo;
2875
0
  primary->Polyline = update_message_Polyline;
2876
0
  primary->MemBlt = update_message_MemBlt;
2877
0
  primary->Mem3Blt = update_message_Mem3Blt;
2878
0
  primary->SaveBitmap = update_message_SaveBitmap;
2879
0
  primary->GlyphIndex = update_message_GlyphIndex;
2880
0
  primary->FastIndex = update_message_FastIndex;
2881
0
  primary->FastGlyph = update_message_FastGlyph;
2882
0
  primary->PolygonSC = update_message_PolygonSC;
2883
0
  primary->PolygonCB = update_message_PolygonCB;
2884
0
  primary->EllipseSC = update_message_EllipseSC;
2885
0
  primary->EllipseCB = update_message_EllipseCB;
2886
  /* Secondary Update */
2887
0
  message->CacheBitmap = secondary->CacheBitmap;
2888
0
  message->CacheBitmapV2 = secondary->CacheBitmapV2;
2889
0
  message->CacheBitmapV3 = secondary->CacheBitmapV3;
2890
0
  message->CacheColorTable = secondary->CacheColorTable;
2891
0
  message->CacheGlyph = secondary->CacheGlyph;
2892
0
  message->CacheGlyphV2 = secondary->CacheGlyphV2;
2893
0
  message->CacheBrush = secondary->CacheBrush;
2894
0
  secondary->CacheBitmap = update_message_CacheBitmap;
2895
0
  secondary->CacheBitmapV2 = update_message_CacheBitmapV2;
2896
0
  secondary->CacheBitmapV3 = update_message_CacheBitmapV3;
2897
0
  secondary->CacheColorTable = update_message_CacheColorTable;
2898
0
  secondary->CacheGlyph = update_message_CacheGlyph;
2899
0
  secondary->CacheGlyphV2 = update_message_CacheGlyphV2;
2900
0
  secondary->CacheBrush = update_message_CacheBrush;
2901
  /* Alternate Secondary Update */
2902
0
  message->CreateOffscreenBitmap = altsec->CreateOffscreenBitmap;
2903
0
  message->SwitchSurface = altsec->SwitchSurface;
2904
0
  message->CreateNineGridBitmap = altsec->CreateNineGridBitmap;
2905
0
  message->FrameMarker = altsec->FrameMarker;
2906
0
  message->StreamBitmapFirst = altsec->StreamBitmapFirst;
2907
0
  message->StreamBitmapNext = altsec->StreamBitmapNext;
2908
0
  message->DrawGdiPlusFirst = altsec->DrawGdiPlusFirst;
2909
0
  message->DrawGdiPlusNext = altsec->DrawGdiPlusNext;
2910
0
  message->DrawGdiPlusEnd = altsec->DrawGdiPlusEnd;
2911
0
  message->DrawGdiPlusCacheFirst = altsec->DrawGdiPlusCacheFirst;
2912
0
  message->DrawGdiPlusCacheNext = altsec->DrawGdiPlusCacheNext;
2913
0
  message->DrawGdiPlusCacheEnd = altsec->DrawGdiPlusCacheEnd;
2914
0
  altsec->CreateOffscreenBitmap = update_message_CreateOffscreenBitmap;
2915
0
  altsec->SwitchSurface = update_message_SwitchSurface;
2916
0
  altsec->CreateNineGridBitmap = update_message_CreateNineGridBitmap;
2917
0
  altsec->FrameMarker = update_message_FrameMarker;
2918
0
  altsec->StreamBitmapFirst = update_message_StreamBitmapFirst;
2919
0
  altsec->StreamBitmapNext = update_message_StreamBitmapNext;
2920
0
  altsec->DrawGdiPlusFirst = update_message_DrawGdiPlusFirst;
2921
0
  altsec->DrawGdiPlusNext = update_message_DrawGdiPlusNext;
2922
0
  altsec->DrawGdiPlusEnd = update_message_DrawGdiPlusEnd;
2923
0
  altsec->DrawGdiPlusCacheFirst = update_message_DrawGdiPlusCacheFirst;
2924
0
  altsec->DrawGdiPlusCacheNext = update_message_DrawGdiPlusCacheNext;
2925
0
  altsec->DrawGdiPlusCacheEnd = update_message_DrawGdiPlusCacheEnd;
2926
  /* Window Update */
2927
0
  message->WindowCreate = window->WindowCreate;
2928
0
  message->WindowUpdate = window->WindowUpdate;
2929
0
  message->WindowIcon = window->WindowIcon;
2930
0
  message->WindowCachedIcon = window->WindowCachedIcon;
2931
0
  message->WindowDelete = window->WindowDelete;
2932
0
  message->NotifyIconCreate = window->NotifyIconCreate;
2933
0
  message->NotifyIconUpdate = window->NotifyIconUpdate;
2934
0
  message->NotifyIconDelete = window->NotifyIconDelete;
2935
0
  message->MonitoredDesktop = window->MonitoredDesktop;
2936
0
  message->NonMonitoredDesktop = window->NonMonitoredDesktop;
2937
0
  window->WindowCreate = update_message_WindowCreate;
2938
0
  window->WindowUpdate = update_message_WindowUpdate;
2939
0
  window->WindowIcon = update_message_WindowIcon;
2940
0
  window->WindowCachedIcon = update_message_WindowCachedIcon;
2941
0
  window->WindowDelete = update_message_WindowDelete;
2942
0
  window->NotifyIconCreate = update_message_NotifyIconCreate;
2943
0
  window->NotifyIconUpdate = update_message_NotifyIconUpdate;
2944
0
  window->NotifyIconDelete = update_message_NotifyIconDelete;
2945
0
  window->MonitoredDesktop = update_message_MonitoredDesktop;
2946
0
  window->NonMonitoredDesktop = update_message_NonMonitoredDesktop;
2947
  /* Pointer Update */
2948
0
  message->PointerPosition = pointer->PointerPosition;
2949
0
  message->PointerSystem = pointer->PointerSystem;
2950
0
  message->PointerColor = pointer->PointerColor;
2951
0
  message->PointerLarge = pointer->PointerLarge;
2952
0
  message->PointerNew = pointer->PointerNew;
2953
0
  message->PointerCached = pointer->PointerCached;
2954
0
  pointer->PointerPosition = update_message_PointerPosition;
2955
0
  pointer->PointerSystem = update_message_PointerSystem;
2956
0
  pointer->PointerColor = update_message_PointerColor;
2957
0
  pointer->PointerLarge = update_message_PointerLarge;
2958
0
  pointer->PointerNew = update_message_PointerNew;
2959
0
  pointer->PointerCached = update_message_PointerCached;
2960
0
  return TRUE;
2961
0
}
2962
2963
static DWORD WINAPI update_message_proxy_thread(LPVOID arg)
2964
0
{
2965
0
  rdpUpdate* update = (rdpUpdate*)arg;
2966
0
  wMessage message = WINPR_C_ARRAY_INIT;
2967
0
  rdp_update_internal* up = update_cast(update);
2968
2969
0
  while (MessageQueue_Wait(up->queue))
2970
0
  {
2971
0
    int status = 0;
2972
2973
0
    if (MessageQueue_Peek(up->queue, &message, TRUE))
2974
0
      status = update_message_queue_process_message(update, &message);
2975
2976
0
    if (!status)
2977
0
      break;
2978
0
  }
2979
2980
0
  ExitThread(0);
2981
0
  return 0;
2982
0
}
2983
2984
rdpUpdateProxy* update_message_proxy_new(rdpUpdate* update)
2985
0
{
2986
0
  rdpUpdateProxy* message = nullptr;
2987
2988
0
  if (!update)
2989
0
    return nullptr;
2990
2991
0
  if (!(message = (rdpUpdateProxy*)calloc(1, sizeof(rdpUpdateProxy))))
2992
0
    return nullptr;
2993
2994
0
  message->update = update;
2995
0
  update_message_register_interface(message, update);
2996
2997
0
  if (!(message->thread =
2998
0
            CreateThread(nullptr, 0, update_message_proxy_thread, update, 0, nullptr)))
2999
0
  {
3000
0
    WLog_ERR(TAG, "Failed to create proxy thread");
3001
0
    free(message);
3002
0
    return nullptr;
3003
0
  }
3004
3005
0
  return message;
3006
0
}
3007
3008
void update_message_proxy_free(rdpUpdateProxy* message)
3009
0
{
3010
0
  if (message)
3011
0
  {
3012
0
    rdp_update_internal* up = update_cast(message->update);
3013
0
    if (MessageQueue_PostQuit(up->queue, 0))
3014
0
      (void)WaitForSingleObject(message->thread, INFINITE);
3015
3016
0
    (void)CloseHandle(message->thread);
3017
0
    free(message);
3018
0
  }
3019
0
}
3020
3021
/* Event Queue */
3022
static int input_message_free_input_class(wMessage* msg, int type)
3023
0
{
3024
0
  int status = 0;
3025
3026
0
  WINPR_UNUSED(msg);
3027
3028
0
  switch (type)
3029
0
  {
3030
0
    case Input_SynchronizeEvent:
3031
0
      break;
3032
3033
0
    case Input_KeyboardEvent:
3034
0
      break;
3035
3036
0
    case Input_UnicodeKeyboardEvent:
3037
0
      break;
3038
3039
0
    case Input_MouseEvent:
3040
0
      break;
3041
3042
0
    case Input_ExtendedMouseEvent:
3043
0
      break;
3044
3045
0
    case Input_FocusInEvent:
3046
0
      break;
3047
3048
0
    case Input_KeyboardPauseEvent:
3049
0
      break;
3050
3051
0
    default:
3052
0
      status = -1;
3053
0
      break;
3054
0
  }
3055
3056
0
  return status;
3057
0
}
3058
3059
static int input_message_process_input_class(rdpInputProxy* proxy, wMessage* msg, int type)
3060
0
{
3061
0
  int status = 0;
3062
3063
0
  if (!proxy || !msg)
3064
0
    return -1;
3065
3066
0
  switch (type)
3067
0
  {
3068
0
    case Input_SynchronizeEvent:
3069
0
      IFCALL(proxy->SynchronizeEvent, msg->context, (UINT32)(size_t)msg->wParam);
3070
0
      break;
3071
3072
0
    case Input_KeyboardEvent:
3073
0
      IFCALL(proxy->KeyboardEvent, msg->context, (UINT16)(size_t)msg->wParam,
3074
0
             (UINT8)(size_t)msg->lParam);
3075
0
      break;
3076
3077
0
    case Input_UnicodeKeyboardEvent:
3078
0
      IFCALL(proxy->UnicodeKeyboardEvent, msg->context, (UINT16)(size_t)msg->wParam,
3079
0
             (UINT16)(size_t)msg->lParam);
3080
0
      break;
3081
3082
0
    case Input_MouseEvent:
3083
0
    {
3084
0
      UINT32 pos = 0;
3085
0
      UINT16 x = 0;
3086
0
      UINT16 y = 0;
3087
0
      pos = (UINT32)(size_t)msg->lParam;
3088
0
      x = ((pos & 0xFFFF0000) >> 16);
3089
0
      y = (pos & 0x0000FFFF);
3090
0
      IFCALL(proxy->MouseEvent, msg->context, (UINT16)(size_t)msg->wParam, x, y);
3091
0
    }
3092
0
    break;
3093
3094
0
    case Input_ExtendedMouseEvent:
3095
0
    {
3096
0
      UINT32 pos = 0;
3097
0
      UINT16 x = 0;
3098
0
      UINT16 y = 0;
3099
0
      pos = (UINT32)(size_t)msg->lParam;
3100
0
      x = ((pos & 0xFFFF0000) >> 16);
3101
0
      y = (pos & 0x0000FFFF);
3102
0
      IFCALL(proxy->ExtendedMouseEvent, msg->context, (UINT16)(size_t)msg->wParam, x, y);
3103
0
    }
3104
0
    break;
3105
3106
0
    case Input_FocusInEvent:
3107
0
      IFCALL(proxy->FocusInEvent, msg->context, (UINT16)(size_t)msg->wParam);
3108
0
      break;
3109
3110
0
    case Input_KeyboardPauseEvent:
3111
0
      IFCALL(proxy->KeyboardPauseEvent, msg->context);
3112
0
      break;
3113
3114
0
    default:
3115
0
      status = -1;
3116
0
      break;
3117
0
  }
3118
3119
0
  return status;
3120
0
}
3121
3122
static int input_message_free_class(wMessage* msg, int msgClass, int msgType)
3123
0
{
3124
0
  int status = 0;
3125
3126
0
  switch (msgClass)
3127
0
  {
3128
0
    case Input_Class:
3129
0
      status = input_message_free_input_class(msg, msgType);
3130
0
      break;
3131
3132
0
    default:
3133
0
      status = -1;
3134
0
      break;
3135
0
  }
3136
3137
0
  if (status < 0)
3138
0
    WLog_ERR(TAG, "Unknown event: class: %d type: %d", msgClass, msgType);
3139
3140
0
  return status;
3141
0
}
3142
3143
static int input_message_process_class(rdpInputProxy* proxy, wMessage* msg, int msgClass,
3144
                                       int msgType)
3145
0
{
3146
0
  int status = 0;
3147
3148
0
  switch (msgClass)
3149
0
  {
3150
0
    case Input_Class:
3151
0
      status = input_message_process_input_class(proxy, msg, msgType);
3152
0
      break;
3153
3154
0
    default:
3155
0
      status = -1;
3156
0
      break;
3157
0
  }
3158
3159
0
  if (status < 0)
3160
0
    WLog_ERR(TAG, "Unknown event: class: %d type: %d", msgClass, msgType);
3161
3162
0
  return status;
3163
0
}
3164
3165
int input_message_queue_free_message(wMessage* message)
3166
0
{
3167
0
  int status = 0;
3168
0
  int msgClass = 0;
3169
0
  int msgType = 0;
3170
3171
0
  if (!message)
3172
0
    return -1;
3173
3174
0
  if (message->id == WMQ_QUIT)
3175
0
    return 0;
3176
3177
0
  msgClass = GetMessageClass(message->id);
3178
0
  msgType = GetMessageType(message->id);
3179
0
  status = input_message_free_class(message, msgClass, msgType);
3180
3181
0
  if (status < 0)
3182
0
    return -1;
3183
3184
0
  return 1;
3185
0
}
3186
3187
int input_message_queue_process_message(rdpInput* input, wMessage* message)
3188
0
{
3189
0
  int status = 0;
3190
0
  int msgClass = 0;
3191
0
  int msgType = 0;
3192
0
  rdp_input_internal* in = input_cast(input);
3193
3194
0
  if (!message)
3195
0
    return -1;
3196
3197
0
  if (message->id == WMQ_QUIT)
3198
0
    return 0;
3199
3200
0
  msgClass = GetMessageClass(message->id);
3201
0
  msgType = GetMessageType(message->id);
3202
0
  status = input_message_process_class(in->proxy, message, msgClass, msgType);
3203
0
  input_message_free_class(message, msgClass, msgType);
3204
3205
0
  if (status < 0)
3206
0
    return -1;
3207
3208
0
  return 1;
3209
0
}
3210
3211
int input_message_queue_process_pending_messages(rdpInput* input)
3212
0
{
3213
0
  int status = 1;
3214
0
  wMessage message = WINPR_C_ARRAY_INIT;
3215
0
  rdp_input_internal* in = input_cast(input);
3216
3217
0
  if (!in->queue)
3218
0
    return -1;
3219
3220
0
  wMessageQueue* queue = in->queue;
3221
3222
0
  while (MessageQueue_Peek(queue, &message, TRUE))
3223
0
  {
3224
0
    status = input_message_queue_process_message(input, &message);
3225
3226
0
    if (!status)
3227
0
      break;
3228
0
  }
3229
3230
0
  return status;
3231
0
}