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