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