1 /**
2 * FreeRDP: A Remote Desktop Protocol Server
3 * freerdp wrapper
4 *
5 * Copyright 2011-2013 Jay Sorg
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 #if defined(HAVE_CONFIG_H)
21 #include <config_ac.h>
22 #endif
23
24 #include "xrdp-neutrinordp.h"
25 #include "xrdp-color.h"
26 #include "xrdp_rail.h"
27 #include "trans.h"
28 #include "log.h"
29 #include "string_calls.h"
30 #include <freerdp/settings.h>
31
32 #if defined(VERSION_STRUCT_RDP_FREERDP)
33 #if VERSION_STRUCT_RDP_FREERDP > 1
34 #define NEUTRINORDP_HAS_SUPPRESS_OUTPUT
35 #endif
36 #endif
37
38 /* Max amount of buffered output data before we stop generating more */
39 #define MAX_QUEUED_MODULE_OUTPUT_DATA 50000
40
41
42 struct mod_context
43 {
44 rdpContext _p;
45 struct mod *modi;
46 };
47 typedef struct mod_context modContext;
48
49 /*****************************************************************************/
50 static void
verifyColorMap(struct mod * mod)51 verifyColorMap(struct mod *mod)
52 {
53 int i;
54
55 for (i = 0; i < 255; i++)
56 {
57 if (mod->colormap[i] != 0)
58 {
59 return ;
60 }
61 }
62
63 LOG(LOG_LEVEL_WARNING, "The colormap is all NULL");
64 }
65
66 /*****************************************************************************/
67 static int
get_queued_module_output_data(struct mod * mod)68 get_queued_module_output_data(struct mod *mod)
69 {
70 return (mod->si != NULL) ? mod->si->source[XRDP_SOURCE_MOD] : 0;
71 }
72
73 /*****************************************************************************/
74 /* return error */
75 static int
lxrdp_start(struct mod * mod,int w,int h,int bpp)76 lxrdp_start(struct mod *mod, int w, int h, int bpp)
77 {
78 rdpSettings *settings;
79
80 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_start: w %d h %d bpp %d", w, h, bpp);
81 settings = mod->inst->settings;
82 settings->width = w;
83 settings->height = h;
84 settings->color_depth = bpp;
85 mod->bpp = bpp;
86
87 settings->encryption = 1;
88 settings->tls_security = 1;
89 settings->nla_security = 0;
90 settings->rdp_security = 1;
91
92 return 0;
93 }
94
95 /******************************************************************************/
96 /* return error */
97 static void
set_keyboard_overrides(struct mod * mod)98 set_keyboard_overrides(struct mod *mod)
99 {
100 const struct kbd_overrides *ko = &mod->kbd_overrides;
101 rdpSettings *settings = mod->inst->settings;
102
103 if (mod->allow_client_kbd_settings)
104 {
105 settings->kbd_type = mod->client_info.keyboard_type;
106 settings->kbd_subtype = mod->client_info.keyboard_subtype;
107 /* Define the most common number of function keys, 12.
108 because we can't get it from client. */
109 settings->kbd_fn_keys = 12;
110 settings->kbd_layout = mod->client_info.keylayout;
111
112 /* Exception processing for each RDP Keyboard type */
113 if (mod->client_info.keyboard_type == 0x00)
114 {
115 /* 0x00000000 : Set on Server */
116 LOG(LOG_LEVEL_WARNING, "keyboard_type:[0x%02x] ,Set on Server",
117 mod->client_info.keyboard_type);
118 }
119 else if (mod->client_info.keyboard_type == 0x04)
120 {
121 /* 0x00000004 : IBM enhanced (101- or 102-key) keyboard */
122 /* Nothing to do. */
123 }
124 else if (mod->client_info.keyboard_type == 0x07)
125 {
126 /* 0x00000007 : Japanese keyboard */
127 /* Nothing to do. */
128 }
129 }
130
131 if (ko->type != 0)
132 {
133 LOG(LOG_LEVEL_INFO, "overrode kbd_type 0x%02X with 0x%02X",
134 settings->kbd_type, ko->type);
135 settings->kbd_type = ko->type;
136 }
137
138 if (ko->subtype != 0)
139 {
140 LOG(LOG_LEVEL_INFO, "overrode kbd_subtype 0x%02X with 0x%02X",
141 settings->kbd_subtype, ko->subtype);
142 settings->kbd_subtype = ko->subtype;
143 }
144
145 if (ko->fn_keys != 0)
146 {
147 LOG(LOG_LEVEL_INFO, "overrode kbd_fn_keys %d with %d",
148 settings->kbd_fn_keys, ko->fn_keys);
149 settings->kbd_fn_keys = ko->fn_keys;
150 }
151
152 if (ko->layout != 0)
153 {
154 LOG(LOG_LEVEL_INFO, "overrode kbd_layout 0x%08X with 0x%08X",
155 settings->kbd_layout, ko->layout);
156 settings->kbd_layout = ko->layout;
157 }
158
159 if (ko->layout_mask != 0)
160 {
161 LOG(LOG_LEVEL_INFO, "Masked kbd_layout 0x%08X to 0x%08X",
162 settings->kbd_layout, settings->kbd_layout & ko->layout_mask);
163 settings->kbd_layout &= ko->layout_mask;
164 }
165
166 LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy remote keyboard settings, "
167 "kbd_type:[0x%02X], kbd_subtype:[0x%02X], "
168 "kbd_fn_keys:[%02d], kbd_layout:[0x%08X]",
169 settings->kbd_type, settings->kbd_subtype,
170 settings->kbd_fn_keys, settings->kbd_layout);
171 }
172
173 static int
lxrdp_connect(struct mod * mod)174 lxrdp_connect(struct mod *mod)
175 {
176 boolean ok;
177 set_keyboard_overrides(mod);
178
179 LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_connect:");
180
181 ok = freerdp_connect(mod->inst);
182 LOG_DEVEL(LOG_LEVEL_INFO, "lxrdp_connect: freerdp_connect returned %d", ok);
183
184 if (!ok)
185 {
186 LOG_DEVEL(LOG_LEVEL_INFO, "Failure to connect");
187 #ifdef ERRORSTART
188
189 if (connectErrorCode != 0)
190 {
191 char buf[128];
192
193 if (connectErrorCode < ERRORSTART)
194 {
195 if (strerror_r(connectErrorCode, buf, 128) != 0)
196 {
197 g_snprintf(buf, 128, "Errorcode from connect : %d", connectErrorCode);
198 }
199 }
200 else
201 {
202 switch (connectErrorCode)
203 {
204 case PREECONNECTERROR:
205 g_snprintf(buf, 128, "The error code from connect is "
206 "PREECONNECTERROR");
207 break;
208
209 case UNDEFINEDCONNECTERROR:
210 g_snprintf(buf, 128, "The error code from connect is "
211 "UNDEFINEDCONNECTERROR");
212 break;
213
214 case POSTCONNECTERROR:
215 g_snprintf(buf, 128, "The error code from connect is "
216 "POSTCONNECTERROR");
217 break;
218
219 case DNSERROR:
220 g_snprintf(buf, 128, "The DNS system generated an error");
221 break;
222
223 case DNSNAMENOTFOUND:
224 g_snprintf(buf, 128, "The DNS system could not find the "
225 "specified name");
226 break;
227
228 case CONNECTERROR:
229 g_snprintf(buf, 128, "A general connect error was returned");
230 break;
231
232 case MCSCONNECTINITIALERROR:
233 g_snprintf(buf, 128, "The error code from connect is "
234 "MCSCONNECTINITIALERROR");
235 break;
236
237 case TLSCONNECTERROR:
238 g_snprintf(buf, 128, "Error in TLS handshake");
239 break;
240
241 case AUTHENTICATIONERROR:
242 g_snprintf(buf, 128, "Authentication error check your password "
243 "and username");
244 break;
245
246 case INSUFFICIENTPRIVILEGESERROR:
247 g_snprintf(buf, 128, "Insufficent privileges on target server");
248 break;
249
250 default:
251 g_snprintf(buf, 128, "Unhandled Errorcode from connect : %d",
252 connectErrorCode);
253 break;
254 }
255 }
256
257 LOG(LOG_LEVEL_INFO, buf);
258 mod->server_msg(mod, buf, 0);
259 }
260
261 #endif
262 LOG(LOG_LEVEL_ERROR, "NeutrinoRDP proxy connection: status [Failed],"
263 " RDP client [%s:%s], RDP server [%s:%d], RDP server username [%s],"
264 " xrdp pamusername [%s], xrdp process id [%d]",
265 mod->client_info.client_addr,
266 mod->client_info.client_port,
267 mod->inst->settings->hostname,
268 mod->inst->settings->port,
269 mod->inst->settings->username,
270 mod->pamusername,
271 g_getpid());
272 return 1;
273 }
274 else
275 {
276 LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Success],"
277 " RDP client [%s:%s], RDP server [%s:%d], RDP server username [%s],"
278 " xrdp pamusername [%s], xrdp process id [%d]",
279 mod->client_info.client_addr,
280 mod->client_info.client_port,
281 mod->inst->settings->hostname,
282 mod->inst->settings->port,
283 mod->inst->settings->username,
284 mod->pamusername,
285 g_getpid());
286 }
287
288 return 0;
289 }
290
291 /******************************************************************************/
292 /* return error */
293 static int
lxrdp_event(struct mod * mod,int msg,long param1,long param2,long param3,long param4)294 lxrdp_event(struct mod *mod, int msg, long param1, long param2,
295 long param3, long param4)
296 {
297 int x;
298 int y;
299 int cx;
300 int cy;
301 int flags;
302 int size;
303 int total_size;
304 int chanid;
305 int lchid;
306 char *data;
307
308 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_event: msg %d", msg);
309
310 switch (msg)
311 {
312 case 15: /* key down */
313
314 /* Before we handle the first character we synchronize
315 capslock and numlock. */
316 /* We collect the state during the first synchronize
317 ( see msg 17) */
318 if (!mod->bool_keyBoardSynced)
319 {
320 LOG_DEVEL(LOG_LEVEL_DEBUG, "Additional Sync event handled : %d", mod->keyBoardLockInfo);
321 mod->inst->input->SynchronizeEvent(mod->inst->input, mod->keyBoardLockInfo);
322 mod->bool_keyBoardSynced = 1;
323 }
324
325 mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
326 break;
327
328 case 16: /* key up */
329 mod->inst->input->KeyboardEvent(mod->inst->input, param4, param3);
330 break;
331
332 case 17: /* Synchronize */
333 LOG_DEVEL(LOG_LEVEL_DEBUG, "Synchronized event handled : %ld", param1);
334 /* In some situations the Synchronize event come to early.
335 Therefore we store this information and use it when we
336 receive the first keyboard event
337 Without this fix numlock and capslock can come
338 out of sync. */
339 mod->inst->input->SynchronizeEvent(mod->inst->input, param1);
340
341 if (!mod->bool_keyBoardSynced)
342 {
343 mod->keyBoardLockInfo = param1;
344 }
345
346 break;
347
348 case 100: /* mouse move */
349 LOG_DEVEL(LOG_LEVEL_DEBUG, "mouse move %ld %ld", param1, param2);
350 x = param1;
351 y = param2;
352 flags = PTR_FLAGS_MOVE;
353 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
354 break;
355
356 case 101: /* left button up */
357 LOG_DEVEL(LOG_LEVEL_DEBUG, "left button up %ld %ld", param1, param2);
358 x = param1;
359 y = param2;
360 flags = PTR_FLAGS_BUTTON1;
361 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
362 break;
363
364 case 102: /* left button down */
365 LOG_DEVEL(LOG_LEVEL_DEBUG, "left button down %ld %ld", param1, param2);
366 x = param1;
367 y = param2;
368 flags = PTR_FLAGS_BUTTON1 | PTR_FLAGS_DOWN;
369 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
370 break;
371
372 case 103: /* right button up */
373 LOG_DEVEL(LOG_LEVEL_DEBUG, "right button up %ld %ld", param1, param2);
374 x = param1;
375 y = param2;
376 flags = PTR_FLAGS_BUTTON2;
377 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
378 break;
379
380 case 104: /* right button down */
381 LOG_DEVEL(LOG_LEVEL_DEBUG, "right button down %ld %ld", param1, param2);
382 x = param1;
383 y = param2;
384 flags = PTR_FLAGS_BUTTON2 | PTR_FLAGS_DOWN;
385 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
386 break;
387
388 case 105: /* middle button up */
389 LOG_DEVEL(LOG_LEVEL_DEBUG, "middle button up %ld %ld", param1, param2);
390 x = param1;
391 y = param2;
392 flags = PTR_FLAGS_BUTTON3;
393 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
394 break;
395
396 case 106: /* middle button down */
397 LOG_DEVEL(LOG_LEVEL_DEBUG, "middle button down %ld %ld", param1, param2);
398 x = param1;
399 y = param2;
400 flags = PTR_FLAGS_BUTTON3 | PTR_FLAGS_DOWN;
401 mod->inst->input->MouseEvent(mod->inst->input, flags, x, y);
402 break;
403
404 case 107: /* wheel up */
405 flags = PTR_FLAGS_WHEEL | 0x0078;
406 mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
407 break;
408
409 case 108:
410 break;
411
412 case 109: /* wheel down */
413 flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088;
414 mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0);
415 break;
416
417 case 110:
418 break;
419
420 case 200:
421 LOG_DEVEL(LOG_LEVEL_DEBUG, "Invalidate request sent from client");
422 x = (param1 >> 16) & 0xffff;
423 y = (param1 >> 0) & 0xffff;
424 cx = (param2 >> 16) & 0xffff;
425 cy = (param2 >> 0) & 0xffff;
426 mod->inst->SendInvalidate(mod->inst, -1, x, y, cx, cy);
427 break;
428
429 case 0x5555:
430 chanid = LOWORD(param1);
431 flags = HIWORD(param1);
432 size = (int)param2;
433 data = (char *)param3;
434 total_size = (int)param4;
435
436 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags);
437
438 if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels))
439 {
440 LOG(LOG_LEVEL_WARNING, "lxrdp_event: error chanid %d", chanid);
441 break;
442 }
443
444 lchid = mod->inst->settings->channels[chanid].channel_id;
445
446 switch (flags & 3)
447 {
448 case 3:
449 mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)data, total_size);
450 break;
451
452 case 2:
453 /* end */
454 g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
455 mod->chan_buf_valid += size;
456 mod->inst->SendChannelData(mod->inst, lchid, (tui8 *)(mod->chan_buf),
457 total_size);
458 g_free(mod->chan_buf);
459 mod->chan_buf = 0;
460 mod->chan_buf_bytes = 0;
461 mod->chan_buf_valid = 0;
462 break;
463
464 case 1:
465 /* start */
466 g_free(mod->chan_buf);
467 mod->chan_buf = (char *)g_malloc(total_size, 0);
468 mod->chan_buf_bytes = total_size;
469 mod->chan_buf_valid = 0;
470 g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
471 mod->chan_buf_valid += size;
472 break;
473
474 default:
475 /* middle */
476 g_memcpy(mod->chan_buf + mod->chan_buf_valid, data, size);
477 mod->chan_buf_valid += size;
478 break;
479 }
480
481 break;
482
483 default:
484 LOG(LOG_LEVEL_WARNING, "Unhandled message type in eventhandler %d", msg);
485 break;
486 }
487
488 return 0;
489 }
490
491 /******************************************************************************/
492 /* return error */
493 static int
lxrdp_signal(struct mod * mod)494 lxrdp_signal(struct mod *mod)
495 {
496 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_signal:");
497 return 0;
498 }
499
500 /******************************************************************************/
501 /* return error */
502 static int
lxrdp_end(struct mod * mod)503 lxrdp_end(struct mod *mod)
504 {
505 int i;
506 int j;
507
508 for (j = 0; j < 4; j++)
509 {
510 for (i = 0; i < 4096; i++)
511 {
512 g_free(mod->bitmap_cache[j][i].data);
513 }
514 }
515
516 for (i = 0; i < 64; i++)
517 {
518 if (mod->brush_cache[i].data != mod->brush_cache[i].b8x8)
519 {
520 g_free(mod->brush_cache[i].data);
521 }
522 }
523
524 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_end:");
525 LOG(LOG_LEVEL_INFO, "NeutrinoRDP proxy connection: status [Disconnect],"
526 " RDP client [%s:%s], RDP server [%s:%d], RDP server username [%s],"
527 " xrdp pamusername [%s], xrdp process id [%d]",
528 mod->client_info.client_addr,
529 mod->client_info.client_port,
530 mod->inst->settings->hostname,
531 mod->inst->settings->port,
532 mod->inst->settings->username,
533 mod->pamusername,
534 g_getpid());
535 return 0;
536 }
537
538 /******************************************************************************/
539 /* return error */
540 static int
lxrdp_set_param(struct mod * mod,const char * name,const char * value)541 lxrdp_set_param(struct mod *mod, const char *name, const char *value)
542 {
543 rdpSettings *settings;
544
545 if (g_strcmp(name, "password") == 0 || g_strcmp(name, "pampassword") == 0)
546 {
547 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_set_param: name [%s] value [******]", name);
548 }
549 else
550 {
551 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_set_param: name [%s] value [%s]", name, value);
552 }
553
554 settings = mod->inst->settings;
555
556 if (g_strcmp(name, "hostname") == 0)
557 {
558 }
559 else if (g_strcmp(name, "ip") == 0)
560 {
561 settings->hostname = g_strdup(value);
562 }
563 else if (g_strcmp(name, "port") == 0)
564 {
565 settings->port = g_atoi(value);
566 }
567 else if (g_strcmp(name, "keylayout") == 0)
568 {
569 LOG(LOG_LEVEL_DEBUG, "%s:[0x%08X]", name, g_atoi(value));
570 }
571 else if (g_strcmp(name, "name") == 0)
572 {
573 }
574 else if (g_strcmp(name, "lib") == 0)
575 {
576 }
577 else if (g_strcmp(name, "username") == 0)
578 {
579 g_strncpy(mod->username, value, 255);
580 }
581 else if (g_strcmp(name, "domain") == 0)
582 {
583 g_strncpy(mod->domain, value, 255);
584 }
585 else if (g_strcmp(name, "password") == 0)
586 {
587 g_strncpy(mod->password, value, 255);
588 }
589 else if (g_strcmp(name, "client_info") == 0)
590 {
591 g_memcpy(&(mod->client_info), value, sizeof(mod->client_info));
592 /* This is a Struct and cannot be printed in next else*/
593 LOG_DEVEL(LOG_LEVEL_DEBUG, "Client_info struct ignored");
594 }
595 else if (g_strcmp(name, "program") == 0)
596 {
597 settings->shell = g_strdup(value);
598 }
599 else if (g_strcmp(name, "nla") == 0)
600 {
601 settings->nla_security = g_text2bool(value);
602 }
603 else if (g_strcmp(name, "enable_dynamic_resizing") == 0)
604 {
605 settings->desktop_resize = g_text2bool(value);
606 }
607 else if (g_strcmp(name, "pamusername") == 0)
608 {
609 g_strncpy(mod->pamusername, value, 255);
610 }
611 else if (g_strcmp(name, "pampassword") == 0 ||
612 g_strcmp(name, "pamsessionmng") == 0)
613 {
614 /* Valid (but unused) parameters not logged */
615 }
616 else if (g_strcmp(name, "channel.rdpdr") == 0 ||
617 g_strcmp(name, "channel.rdpsnd") == 0 ||
618 g_strcmp(name, "channel.cliprdr") == 0 ||
619 g_strcmp(name, "channel.drdynvc") == 0)
620 {
621 /* Valid (but unused) parameters not logged */
622 }
623 else if (g_strcmp(name, "perf.allow_client_experiencesettings") == 0)
624 {
625 mod->allow_client_experiencesettings = g_text2bool(value);
626 }
627 else if (g_strcmp(name, "perf.wallpaper") == 0)
628 {
629 mod->perf_settings_override_mask |= PERF_DISABLE_WALLPAPER;
630 if (!g_text2bool(value))
631 {
632 mod->perf_settings_values_mask |= PERF_DISABLE_WALLPAPER;
633 }
634 }
635 else if (g_strcmp(name, "perf.font_smoothing") == 0)
636 {
637 mod->perf_settings_override_mask |= PERF_ENABLE_FONT_SMOOTHING;
638 if (g_text2bool(value))
639 {
640 mod->perf_settings_values_mask |= PERF_ENABLE_FONT_SMOOTHING;
641 }
642 }
643 else if (g_strcmp(name, "perf.desktop_composition") == 0)
644 {
645 mod->perf_settings_override_mask |= PERF_ENABLE_DESKTOP_COMPOSITION;
646 if (g_text2bool(value))
647 {
648 mod->perf_settings_values_mask |= PERF_ENABLE_DESKTOP_COMPOSITION;
649 }
650 }
651 else if (g_strcmp(name, "perf.full_window_drag") == 0)
652 {
653 mod->perf_settings_override_mask |= PERF_DISABLE_FULLWINDOWDRAG;
654 if (!g_text2bool(value))
655 {
656 mod->perf_settings_values_mask |= PERF_DISABLE_FULLWINDOWDRAG;
657 }
658 }
659 else if (g_strcmp(name, "perf.menu_anims") == 0)
660 {
661 mod->perf_settings_override_mask |= PERF_DISABLE_MENUANIMATIONS;
662 if (!g_text2bool(value))
663 {
664 mod->perf_settings_values_mask |= PERF_DISABLE_MENUANIMATIONS;
665 }
666 }
667 else if (g_strcmp(name, "perf.themes") == 0)
668 {
669 mod->perf_settings_override_mask |= PERF_DISABLE_THEMING;
670 if (!g_text2bool(value))
671 {
672 mod->perf_settings_values_mask |= PERF_DISABLE_THEMING;
673 }
674 }
675 else if (g_strcmp(name, "perf.cursor_blink") == 0)
676 {
677 mod->perf_settings_override_mask |= PERF_DISABLE_CURSORSETTINGS;
678 if (!g_text2bool(value))
679 {
680 mod->perf_settings_values_mask |= PERF_DISABLE_CURSORSETTINGS;
681 }
682 }
683 else if (g_strcmp(name, "perf.cursor_shadow") == 0)
684 {
685 mod->perf_settings_override_mask |= PERF_DISABLE_CURSOR_SHADOW;
686 if (!g_text2bool(value))
687 {
688 mod->perf_settings_values_mask |= PERF_DISABLE_CURSOR_SHADOW;
689 }
690 }
691 else if (g_strcmp(name, "neutrinordp.allow_client_keyboardLayout") == 0)
692 {
693 mod->allow_client_kbd_settings = g_text2bool(value);
694 }
695 else if (g_strcmp(name, "neutrinordp.override_keyboardLayout_mask") == 0)
696 {
697 /* Keyboard values are stored for later processing */
698 mod->kbd_overrides.layout_mask = g_atoix(value);
699 }
700 else if (g_strcmp(name, "neutrinordp.override_kbd_type") == 0)
701 {
702 mod->kbd_overrides.type = g_atoix(value);
703 }
704 else if (g_strcmp(name, "neutrinordp.override_kbd_subtype") == 0)
705 {
706 mod->kbd_overrides.subtype = g_atoix(value);
707 }
708 else if (g_strcmp(name, "neutrinordp.override_kbd_fn_keys") == 0)
709 {
710 mod->kbd_overrides.fn_keys = g_atoix(value);
711 }
712 else if (g_strcmp(name, "neutrinordp.override_kbd_layout") == 0)
713 {
714 mod->kbd_overrides.layout = g_atoix(value);
715 }
716 else
717 {
718 LOG(LOG_LEVEL_WARNING, "lxrdp_set_param: unknown name [%s] value [%s]", name, value);
719 }
720
721 return 0;
722 }
723
724 /******************************************************************************/
725 static int
lxrdp_session_change(struct mod * mod,int a,int b)726 lxrdp_session_change(struct mod *mod, int a, int b)
727 {
728 LOG_DEVEL(LOG_LEVEL_DEBUG, "lxrdp_session_change: - no code here");
729 return 0;
730 }
731
732 /******************************************************************************/
733 static int
lxrdp_get_wait_objs(struct mod * mod,tbus * read_objs,int * rcount,tbus * write_objs,int * wcount,int * timeout)734 lxrdp_get_wait_objs(struct mod *mod, tbus *read_objs, int *rcount,
735 tbus *write_objs, int *wcount, int *timeout)
736 {
737 void **rfds;
738 void **wfds;
739 boolean ok;
740
741 LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_get_wait_objs:");
742 /*
743 * Don't check this module for activity if our queued output data
744 * has already reached the limit
745 */
746 if (get_queued_module_output_data(mod) > MAX_QUEUED_MODULE_OUTPUT_DATA)
747 {
748 *rcount = 0;
749 *wcount = 0;
750 }
751 else
752 {
753 rfds = (void **)read_objs;
754 wfds = (void **)write_objs;
755 ok = freerdp_get_fds(mod->inst, rfds, rcount, wfds, wcount);
756
757 if (!ok)
758 {
759 LOG(LOG_LEVEL_ERROR, "lxrdp_get_wait_objs: freerdp_get_fds failed");
760 return 1;
761 }
762 }
763
764 return 0;
765 }
766
767 /******************************************************************************/
768 static int
lxrdp_check_wait_objs(struct mod * mod)769 lxrdp_check_wait_objs(struct mod *mod)
770 {
771 boolean ok;
772
773 LOG_DEVEL(LOG_LEVEL_TRACE, "lxrdp_check_wait_objs:");
774 /*
775 * Only process the freerdp file descriptors if our queued output data
776 * has not reached the limit
777 */
778 if (get_queued_module_output_data(mod) <= MAX_QUEUED_MODULE_OUTPUT_DATA)
779 {
780 /*
781 * Before checking the file descriptors, set the source info
782 * current source, so any data queued on output trans objects
783 * gets attributed to this module
784 */
785 if (mod->si)
786 {
787 mod->si->cur_source = XRDP_SOURCE_MOD;
788 }
789 ok = freerdp_check_fds(mod->inst);
790 if (mod->si)
791 {
792 mod->si->cur_source = XRDP_SOURCE_NONE;
793 }
794
795 if (!ok)
796 {
797 LOG(LOG_LEVEL_ERROR, "lxrdp_check_wait_objs: freerdp_check_fds failed");
798 return 1;
799 }
800 }
801
802 return 0;
803 }
804
805 /******************************************************************************/
806 static int
lxrdp_frame_ack(struct mod * mod,int flags,int frame_id)807 lxrdp_frame_ack(struct mod *mod, int flags, int frame_id)
808 {
809 return 0;
810 }
811
812 /******************************************************************************/
813 static int
lxrdp_suppress_output(struct mod * mod,int suppress,int left,int top,int right,int bottom)814 lxrdp_suppress_output(struct mod *mod, int suppress,
815 int left, int top, int right, int bottom)
816 {
817 #if defined(NEUTRINORDP_HAS_SUPPRESS_OUTPUT)
818 mod->inst->SendSuppressOutput(mod->inst, !suppress, left, top, right, bottom);
819 #endif
820 return 0;
821 }
822
823 /******************************************************************************/
824 static int
lxrdp_server_version_message(struct mod * mod)825 lxrdp_server_version_message(struct mod *mod)
826 {
827 return 0;
828 }
829
830 /******************************************************************************/
831 static int
lxrdp_server_monitor_resize(struct mod * mod,int width,int height)832 lxrdp_server_monitor_resize(struct mod *mod, int width, int height)
833 {
834 return 0;
835 }
836
837 /******************************************************************************/
838 static int
lxrdp_server_monitor_full_invalidate(struct mod * mod,int width,int height)839 lxrdp_server_monitor_full_invalidate(struct mod *mod, int width, int height)
840 {
841 return 0;
842 }
843
844 /******************************************************************************/
845 static void
lfreerdp_begin_paint(rdpContext * context)846 lfreerdp_begin_paint(rdpContext *context)
847 {
848 struct mod *mod;
849
850 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_begin_paint:");
851 mod = ((struct mod_context *)context)->modi;
852 mod->server_begin_update(mod);
853 }
854
855 /******************************************************************************/
856 static void
lfreerdp_end_paint(rdpContext * context)857 lfreerdp_end_paint(rdpContext *context)
858 {
859 struct mod *mod;
860
861 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_end_paint:");
862 mod = ((struct mod_context *)context)->modi;
863 mod->server_end_update(mod);
864 }
865
866 /******************************************************************************/
867 static void
lfreerdp_set_bounds(rdpContext * context,rdpBounds * bounds)868 lfreerdp_set_bounds(rdpContext *context, rdpBounds *bounds)
869 {
870 struct mod *mod;
871 int x;
872 int y;
873 int cx;
874 int cy;
875
876 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_set_bounds: %p", bounds);
877 mod = ((struct mod_context *)context)->modi;
878
879 if (bounds != 0)
880 {
881 x = bounds->left;
882 y = bounds->top;
883 cx = (bounds->right - bounds->left) + 1;
884 cy = (bounds->bottom - bounds->top) + 1;
885 mod->server_set_clip(mod, x, y, cx, cy);
886 }
887 else
888 {
889 mod->server_reset_clip(mod);
890 }
891 }
892
893 /******************************************************************************/
894 static void
lfreerdp_bitmap_update(rdpContext * context,BITMAP_UPDATE * bitmap)895 lfreerdp_bitmap_update(rdpContext *context, BITMAP_UPDATE *bitmap)
896 {
897 struct mod *mod;
898 int index;
899 int cx;
900 int cy;
901 int server_bpp;
902 int server_Bpp;
903 int client_bpp;
904 int j;
905 int line_bytes;
906 BITMAP_DATA *bd;
907 char *dst_data;
908 char *dst_data1;
909 char *src;
910 char *dst;
911
912 mod = ((struct mod_context *)context)->modi;
913 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_bitmap_update: %d %d", bitmap->number, bitmap->count);
914
915 server_bpp = mod->inst->settings->color_depth;
916 server_Bpp = (server_bpp + 7) / 8;
917 client_bpp = mod->bpp;
918
919 for (index = 0; index < bitmap->number; index++)
920 {
921 bd = &bitmap->rectangles[index];
922 cx = (bd->destRight - bd->destLeft) + 1;
923 cy = (bd->destBottom - bd->destTop) + 1;
924 line_bytes = server_Bpp * bd->width;
925 dst_data = (char *)g_malloc(bd->height * line_bytes + 16, 0);
926
927 if (bd->compressed)
928 {
929 LOG_DEVEL(LOG_LEVEL_DEBUG, "decompress size : %d", bd->bitmapLength);
930
931 if (!bitmap_decompress(bd->bitmapDataStream, (tui8 *)dst_data, bd->width,
932 bd->height, bd->bitmapLength, server_bpp, server_bpp))
933 {
934 LOG(LOG_LEVEL_WARNING, "Failure to decompress the bitmap");
935 }
936 }
937 else
938 {
939 /* bitmap is upside down */
940 LOG_DEVEL(LOG_LEVEL_DEBUG, "bitmap upside down");
941 src = (char *)(bd->bitmapDataStream);
942 dst = dst_data + bd->height * line_bytes;
943
944 for (j = 0; j < bd->height; j++)
945 {
946 dst -= line_bytes;
947 g_memcpy(dst, src, line_bytes);
948 src += line_bytes;
949 }
950 }
951
952 dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data,
953 bd->width, bd->height, mod->colormap);
954 mod->server_paint_rect(mod, bd->destLeft, bd->destTop, cx, cy,
955 dst_data1, bd->width, bd->height, 0, 0);
956
957 if (dst_data1 != dst_data)
958 {
959 g_free(dst_data1);
960 }
961
962 g_free(dst_data);
963 }
964 }
965
966 /******************************************************************************/
967 static void
lfreerdp_dst_blt(rdpContext * context,DSTBLT_ORDER * dstblt)968 lfreerdp_dst_blt(rdpContext *context, DSTBLT_ORDER *dstblt)
969 {
970 struct mod *mod;
971
972 mod = ((struct mod_context *)context)->modi;
973 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_dst_blt:");
974 mod->server_set_opcode(mod, dstblt->bRop);
975 mod->server_fill_rect(mod, dstblt->nLeftRect, dstblt->nTopRect,
976 dstblt->nWidth, dstblt->nHeight);
977 mod->server_set_opcode(mod, 0xcc);
978 }
979
980 /******************************************************************************/
981 static void
lfreerdp_pat_blt(rdpContext * context,PATBLT_ORDER * patblt)982 lfreerdp_pat_blt(rdpContext *context, PATBLT_ORDER *patblt)
983 {
984 struct mod *mod;
985 int idx;
986 int fgcolor;
987 int bgcolor;
988 int server_bpp;
989 int client_bpp;
990 struct brush_item *bi;
991
992 mod = ((struct mod_context *)context)->modi;
993 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_pat_blt:");
994
995 server_bpp = mod->inst->settings->color_depth;
996 client_bpp = mod->bpp;
997 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pat_blt: bpp %d %d", server_bpp, client_bpp);
998
999 fgcolor = convert_color(server_bpp, client_bpp,
1000 patblt->foreColor, mod->colormap);
1001 bgcolor = convert_color(server_bpp, client_bpp,
1002 patblt->backColor, mod->colormap);
1003
1004 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pat_blt: nLeftRect %d nTopRect %d "
1005 "nWidth %d nHeight %d fgcolor 0x%8.8x bgcolor 0x%8.8x",
1006 patblt->nLeftRect, patblt->nTopRect,
1007 patblt->nWidth, patblt->nHeight, fgcolor, bgcolor);
1008
1009 if (fgcolor == bgcolor)
1010 {
1011 LOG(LOG_LEVEL_WARNING, "Warning same color on both bg and fg");
1012 }
1013
1014 mod->server_set_mixmode(mod, 1);
1015 mod->server_set_opcode(mod, patblt->bRop);
1016 mod->server_set_fgcolor(mod, fgcolor);
1017 mod->server_set_bgcolor(mod, bgcolor);
1018
1019 if (patblt->brush.style & 0x80)
1020 {
1021 idx = patblt->brush.hatch;
1022
1023 if ((idx < 0) || (idx >= 64))
1024 {
1025 LOG(LOG_LEVEL_ERROR, "lfreerdp_pat_blt: error patblt->brush.hatch, "
1026 "Expected min 0, max 63. Actual %d", idx);
1027 return;
1028 }
1029
1030 bi = mod->brush_cache + idx;
1031 mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y,
1032 3, bi->b8x8);
1033 }
1034 else
1035 {
1036 mod->server_set_brush(mod, patblt->brush.x, patblt->brush.y,
1037 patblt->brush.style,
1038 (char *)(patblt->brush.p8x8));
1039 }
1040
1041 mod->server_fill_rect(mod, patblt->nLeftRect, patblt->nTopRect,
1042 patblt->nWidth, patblt->nHeight);
1043 mod->server_set_opcode(mod, 0xcc);
1044 mod->server_set_mixmode(mod, 0);
1045
1046 }
1047
1048 /******************************************************************************/
1049 static void
lfreerdp_scr_blt(rdpContext * context,SCRBLT_ORDER * scrblt)1050 lfreerdp_scr_blt(rdpContext *context, SCRBLT_ORDER *scrblt)
1051 {
1052 struct mod *mod;
1053
1054 mod = ((struct mod_context *)context)->modi;
1055 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_scr_blt:");
1056 mod->server_set_opcode(mod, scrblt->bRop);
1057 mod->server_screen_blt(mod, scrblt->nLeftRect, scrblt->nTopRect,
1058 scrblt->nWidth, scrblt->nHeight,
1059 scrblt->nXSrc, scrblt->nYSrc);
1060 mod->server_set_opcode(mod, 0xcc);
1061 }
1062
1063 /******************************************************************************/
1064 static void
lfreerdp_opaque_rect(rdpContext * context,OPAQUE_RECT_ORDER * opaque_rect)1065 lfreerdp_opaque_rect(rdpContext *context, OPAQUE_RECT_ORDER *opaque_rect)
1066 {
1067 struct mod *mod;
1068 int server_bpp;
1069 int client_bpp;
1070 int fgcolor;
1071
1072 mod = ((struct mod_context *)context)->modi;
1073 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_opaque_rect:");
1074 server_bpp = mod->inst->settings->color_depth;
1075 client_bpp = mod->bpp;
1076 fgcolor = convert_color(server_bpp, client_bpp,
1077 opaque_rect->color, mod->colormap);
1078 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_opaque_rect: nLeftRect %d nTopRect %d "
1079 "nWidth %d nHeight %d fgcolor 0x%8.8x",
1080 opaque_rect->nLeftRect, opaque_rect->nTopRect,
1081 opaque_rect->nWidth, opaque_rect->nHeight, fgcolor);
1082 mod->server_set_fgcolor(mod, fgcolor);
1083 mod->server_fill_rect(mod, opaque_rect->nLeftRect, opaque_rect->nTopRect,
1084 opaque_rect->nWidth, opaque_rect->nHeight);
1085 }
1086
1087 /******************************************************************************/
1088 static void
lfreerdp_mem_blt(rdpContext * context,MEMBLT_ORDER * memblt)1089 lfreerdp_mem_blt(rdpContext *context, MEMBLT_ORDER *memblt)
1090 {
1091 int id;
1092 int idx;
1093 struct mod *mod;
1094 struct bitmap_item *bi;
1095
1096 mod = ((struct mod_context *)context)->modi;
1097 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_mem_blt: cacheId %d cacheIndex %d",
1098 memblt->cacheId, memblt->cacheIndex);
1099
1100 id = memblt->cacheId;
1101 idx = memblt->cacheIndex;
1102
1103 if (idx == 32767) /* BITMAPCACHE_WAITING_LIST_INDEX */
1104 {
1105 idx = 4096 - 1;
1106 }
1107
1108 if ((id < 0) || (id >= 4))
1109 {
1110 LOG(LOG_LEVEL_ERROR, "lfreerdp_mem_blt: bad id [%d]", id);
1111 return;
1112 }
1113
1114 if ((idx < 0) || (idx >= 4096))
1115 {
1116 LOG(LOG_LEVEL_ERROR, "lfreerdp_mem_blt: bad idx [%d]", idx);
1117 return;
1118 }
1119
1120 bi = &(mod->bitmap_cache[id][idx]);
1121
1122 mod->server_set_opcode(mod, memblt->bRop);
1123 mod->server_paint_rect(mod, memblt->nLeftRect, memblt->nTopRect,
1124 memblt->nWidth, memblt->nHeight,
1125 bi->data, bi->width, bi->height,
1126 memblt->nXSrc, memblt->nYSrc);
1127 mod->server_set_opcode(mod, 0xcc);
1128
1129 }
1130
1131 /******************************************************************************/
1132 static void
lfreerdp_glyph_index(rdpContext * context,GLYPH_INDEX_ORDER * glyph_index)1133 lfreerdp_glyph_index(rdpContext *context, GLYPH_INDEX_ORDER *glyph_index)
1134 {
1135 struct mod *mod;
1136 int server_bpp;
1137 int client_bpp;
1138 int fgcolor;
1139 int bgcolor;
1140 int opLeft;
1141 int opTop;
1142 int opRight;
1143 int opBottom;
1144
1145 mod = ((struct mod_context *)context)->modi;
1146 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_glyph_index:");
1147 server_bpp = mod->inst->settings->color_depth;
1148 client_bpp = mod->bpp;
1149 fgcolor = convert_color(server_bpp, client_bpp,
1150 glyph_index->foreColor, mod->colormap);
1151 bgcolor = convert_color(server_bpp, client_bpp,
1152 glyph_index->backColor, mod->colormap);
1153 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_glyph_index: "
1154 "bkLeft %d bkTop %d width %d height %d "
1155 "opLeft %d opTop %d width %d height %d "
1156 "cbData %d fgcolor 0x%8.8x bgcolor 0x%8.8x fOpRedundant %d",
1157 glyph_index->bkLeft, glyph_index->bkTop,
1158 glyph_index->bkRight - glyph_index->bkLeft,
1159 glyph_index->bkBottom - glyph_index->bkTop,
1160 glyph_index->opLeft, glyph_index->opTop,
1161 glyph_index->opRight - glyph_index->opLeft,
1162 glyph_index->opBottom - glyph_index->opTop,
1163 glyph_index->cbData, fgcolor, bgcolor, glyph_index->fOpRedundant);
1164 mod->server_set_bgcolor(mod, fgcolor);
1165 mod->server_set_fgcolor(mod, bgcolor);
1166 opLeft = glyph_index->opLeft;
1167 opTop = glyph_index->opTop;
1168 opRight = glyph_index->opRight;
1169 opBottom = glyph_index->opBottom;
1170 #if 1
1171
1172 /* workarounds for freerdp not using fOpRedundant in
1173 glyph.c::update_gdi_glyph_index */
1174 if (glyph_index->fOpRedundant)
1175 {
1176 opLeft = glyph_index->bkLeft;
1177 opTop = glyph_index->bkTop;
1178 opRight = glyph_index->bkRight;
1179 opBottom = glyph_index->bkBottom;
1180 }
1181
1182 #endif
1183 mod->server_draw_text(mod, glyph_index->cacheId, glyph_index->flAccel,
1184 glyph_index->fOpRedundant,
1185 glyph_index->bkLeft, glyph_index->bkTop,
1186 glyph_index->bkRight, glyph_index->bkBottom,
1187 opLeft, opTop, opRight, opBottom,
1188 glyph_index->x, glyph_index->y,
1189 (char *)(glyph_index->data), glyph_index->cbData);
1190 }
1191
1192 /******************************************************************************/
1193 static void
lfreerdp_line_to(rdpContext * context,LINE_TO_ORDER * line_to)1194 lfreerdp_line_to(rdpContext *context, LINE_TO_ORDER *line_to)
1195 {
1196 struct mod *mod;
1197 int server_bpp;
1198 int client_bpp;
1199 int fgcolor;
1200 int bgcolor;
1201
1202 mod = ((struct mod_context *)context)->modi;
1203 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_line_to:");
1204 mod->server_set_opcode(mod, line_to->bRop2);
1205 server_bpp = mod->inst->settings->color_depth;
1206 client_bpp = mod->bpp;
1207 fgcolor = convert_color(server_bpp, client_bpp,
1208 line_to->penColor, mod->colormap);
1209 bgcolor = convert_color(server_bpp, client_bpp,
1210 line_to->backColor, mod->colormap);
1211 mod->server_set_fgcolor(mod, fgcolor);
1212 mod->server_set_bgcolor(mod, bgcolor);
1213 mod->server_set_pen(mod, line_to->penStyle, line_to->penWidth);
1214 mod->server_draw_line(mod, line_to->nXStart, line_to->nYStart,
1215 line_to->nXEnd, line_to->nYEnd);
1216 mod->server_set_opcode(mod, 0xcc);
1217 }
1218
1219 /******************************************************************************/
1220 static void
lfreerdp_cache_bitmap(rdpContext * context,CACHE_BITMAP_ORDER * cache_bitmap_order)1221 lfreerdp_cache_bitmap(rdpContext *context, CACHE_BITMAP_ORDER *cache_bitmap_order)
1222 {
1223 LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_cache_bitmap: - no code here");
1224 }
1225
1226 /******************************************************************************/
1227 /* Turn the bitmap upside down*/
1228 static void
lfreerdp_upsidedown(uint8 * destination,CACHE_BITMAP_V2_ORDER * cache_bitmap_v2_order,int server_Bpp)1229 lfreerdp_upsidedown(uint8 *destination, CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order, int server_Bpp)
1230 {
1231 tui8 *src;
1232 tui8 *dst;
1233 int line_bytes;
1234 int j;
1235
1236 if (destination == NULL)
1237 {
1238 LOG(LOG_LEVEL_ERROR, "lfreerdp_upsidedown: destination pointer is NULL !!!");
1239 return;
1240 }
1241
1242 line_bytes = server_Bpp * cache_bitmap_v2_order->bitmapWidth;
1243 src = cache_bitmap_v2_order->bitmapDataStream;
1244 dst = destination + ((cache_bitmap_v2_order->bitmapHeight) * line_bytes);
1245
1246 for (j = 0; j < cache_bitmap_v2_order->bitmapHeight; j++)
1247 {
1248 dst -= line_bytes;
1249 g_memcpy(dst, src, line_bytes);
1250 src += line_bytes;
1251 }
1252 }
1253
1254 /******************************************************************************/
1255 static void
lfreerdp_cache_bitmapV2(rdpContext * context,CACHE_BITMAP_V2_ORDER * cache_bitmap_v2_order)1256 lfreerdp_cache_bitmapV2(rdpContext *context,
1257 CACHE_BITMAP_V2_ORDER *cache_bitmap_v2_order)
1258 {
1259 char *dst_data;
1260 char *dst_data1;
1261 int bytes;
1262 int width;
1263 int height;
1264 int id;
1265 int idx;
1266 int flags;
1267 int server_bpp;
1268 int server_Bpp;
1269 int client_bpp;
1270 struct mod *mod;
1271
1272 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_bitmapV2: %d %d 0x%8.8x compressed %d",
1273 cache_bitmap_v2_order->cacheId,
1274 cache_bitmap_v2_order->cacheIndex,
1275 cache_bitmap_v2_order->flags,
1276 cache_bitmap_v2_order->compressed);
1277
1278 mod = ((struct mod_context *)context)->modi;
1279 id = cache_bitmap_v2_order->cacheId;
1280 idx = cache_bitmap_v2_order->cacheIndex;
1281 flags = cache_bitmap_v2_order->flags;
1282
1283 if (flags & 0x10) /* CBR2_DO_NOT_CACHE */
1284 {
1285 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_bitmapV2: CBR2_DO_NOT_CACHE");
1286 idx = 4096 - 1;
1287 }
1288
1289 if ((id < 0) || (id >= 4))
1290 {
1291 LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_bitmapV2: bad id [%d]", id);
1292 return;
1293 }
1294
1295 if ((idx < 0) || (idx >= 4096))
1296 {
1297 LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_bitmapV2: bad idx [%d]", idx);
1298 return;
1299 }
1300
1301 server_bpp = mod->inst->settings->color_depth;
1302 server_Bpp = (server_bpp + 7) / 8;
1303 client_bpp = mod->bpp;
1304
1305 width = cache_bitmap_v2_order->bitmapWidth;
1306 height = cache_bitmap_v2_order->bitmapHeight;
1307 bytes = width * height * server_Bpp + 16;
1308 dst_data = (char *)g_malloc(bytes, 0);
1309
1310 if (cache_bitmap_v2_order->compressed)
1311 {
1312 bitmap_decompress(cache_bitmap_v2_order->bitmapDataStream,
1313 (tui8 *)dst_data, width, height,
1314 cache_bitmap_v2_order->bitmapLength,
1315 server_bpp, server_bpp);
1316 }
1317 else
1318 {
1319 /* Uncompressed bitmaps are upside down */
1320 lfreerdp_upsidedown((tui8 *)dst_data, cache_bitmap_v2_order, server_Bpp);
1321 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_bitmapV2: upside down progressed");
1322 }
1323
1324 dst_data1 = convert_bitmap(server_bpp, client_bpp, dst_data,
1325 width, height, mod->colormap);
1326 g_free(mod->bitmap_cache[id][idx].data);
1327 mod->bitmap_cache[id][idx].width = width;
1328 mod->bitmap_cache[id][idx].height = height;
1329 mod->bitmap_cache[id][idx].data = dst_data1;
1330
1331 if (dst_data != dst_data1)
1332 {
1333 g_free(dst_data);
1334 }
1335 }
1336
1337 /******************************************************************************/
1338 static void
lfreerdp_cache_glyph(rdpContext * context,CACHE_GLYPH_ORDER * cache_glyph_order)1339 lfreerdp_cache_glyph(rdpContext *context, CACHE_GLYPH_ORDER *cache_glyph_order)
1340 {
1341 int index;
1342 GLYPH_DATA *gd;
1343 struct mod *mod;
1344
1345 mod = ((struct mod_context *)context)->modi;
1346 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_glyph: %d", cache_glyph_order->cGlyphs);
1347
1348 for (index = 0; index < cache_glyph_order->cGlyphs; index++)
1349 {
1350 gd = cache_glyph_order->glyphData[index];
1351 LOG_DEVEL(LOG_LEVEL_DEBUG, " %d %d %d %d %d", gd->cacheIndex, gd->x, gd->y,
1352 gd->cx, gd->cy);
1353 mod->server_add_char(mod, cache_glyph_order->cacheId, gd->cacheIndex,
1354 gd->x, gd->y, gd->cx, gd->cy, (char *)(gd->aj));
1355 free(gd->aj);
1356 gd->aj = 0;
1357 free(gd);
1358 cache_glyph_order->glyphData[index] = 0;
1359 }
1360
1361 free(cache_glyph_order->unicodeCharacters);
1362 cache_glyph_order->unicodeCharacters = 0;
1363 }
1364
1365 /******************************************************************************/
1366 static void
lfreerdp_cache_brush(rdpContext * context,CACHE_BRUSH_ORDER * cache_brush_order)1367 lfreerdp_cache_brush(rdpContext *context, CACHE_BRUSH_ORDER *cache_brush_order)
1368 {
1369 int idx;
1370 int bytes;
1371 int bpp;
1372 int cx;
1373 int cy;
1374 struct mod *mod;
1375
1376 mod = ((struct mod_context *)context)->modi;
1377 bpp = cache_brush_order->bpp;
1378 cx = cache_brush_order->cx;
1379 cy = cache_brush_order->cy;
1380 idx = cache_brush_order->index;
1381 bytes = cache_brush_order->length;
1382 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_brush: bpp %d cx %d cy %d idx %d bytes %d",
1383 bpp, cx, cy, idx, bytes);
1384
1385 if ((idx < 0) || (idx >= 64))
1386 {
1387 LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_brush: error idx %d", idx);
1388 return;
1389 }
1390
1391 if ((bpp != 1) || (cx != 8) || (cy != 8))
1392 {
1393 LOG(LOG_LEVEL_ERROR, "lfreerdp_cache_brush: error unsupported brush "
1394 "bpp %d cx %d cy %d", bpp, cx, cy);
1395 return;
1396 }
1397
1398 mod->brush_cache[idx].bpp = bpp;
1399 mod->brush_cache[idx].width = cx;
1400 mod->brush_cache[idx].height = cy;
1401 mod->brush_cache[idx].data = mod->brush_cache[idx].b8x8;
1402
1403 if (bytes > 8)
1404 {
1405 bytes = 8;
1406 }
1407
1408 g_memset(mod->brush_cache[idx].data, 0, 8);
1409
1410 if (bytes > 0)
1411 {
1412 if (bytes > 8)
1413 {
1414 LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_cache_brush: bytes too big %d", bytes);
1415 bytes = 8;
1416 }
1417
1418 g_memcpy(mod->brush_cache[idx].data, cache_brush_order->data, bytes);
1419 }
1420
1421 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_cache_brush: out bpp %d cx %d cy %d idx %d bytes %d",
1422 bpp, cx, cy, idx, bytes);
1423
1424 free(cache_brush_order->data);
1425 cache_brush_order->data = 0;
1426
1427 }
1428
1429 /******************************************************************************/
1430 static void
lfreerdp_pointer_position(rdpContext * context,POINTER_POSITION_UPDATE * pointer_position)1431 lfreerdp_pointer_position(rdpContext *context,
1432 POINTER_POSITION_UPDATE *pointer_position)
1433 {
1434 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_position: - no code here");
1435 }
1436
1437 /******************************************************************************/
1438 static void
lfreerdp_pointer_system(rdpContext * context,POINTER_SYSTEM_UPDATE * pointer_system)1439 lfreerdp_pointer_system(rdpContext *context,
1440 POINTER_SYSTEM_UPDATE *pointer_system)
1441 {
1442 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_system: - no code here type value = %d", pointer_system->type);
1443 }
1444
1445 /******************************************************************************/
1446 static void
lfreerdp_pointer_color(rdpContext * context,POINTER_COLOR_UPDATE * pointer_color)1447 lfreerdp_pointer_color(rdpContext *context,
1448 POINTER_COLOR_UPDATE *pointer_color)
1449 {
1450 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_color: - no code here");
1451 }
1452
1453 /******************************************************************************/
1454 static int
lfreerdp_get_pixel(void * bits,int width,int height,int bpp,int delta,int x,int y)1455 lfreerdp_get_pixel(void *bits, int width, int height, int bpp,
1456 int delta, int x, int y)
1457 {
1458 int start;
1459 int shift;
1460 int pixel;
1461 tui8 *src8;
1462
1463 if (bpp == 1)
1464 {
1465 src8 = (tui8 *)bits;
1466 start = (y * delta) + x / 8;
1467 shift = x % 8;
1468 pixel = (src8[start] & (0x80 >> shift)) != 0;
1469 return pixel ? 0xffffff : 0;
1470 }
1471 else if (bpp == 32)
1472 {
1473 src8 = (tui8 *)bits;
1474 src8 += y * delta + x * 4;
1475 pixel = ((int *)(src8))[0];
1476 return pixel;
1477 }
1478 else
1479 {
1480 LOG(LOG_LEVEL_WARNING, "lfreerdp_get_pixel: unknown bpp %d", bpp);
1481 }
1482
1483 return 0;
1484 }
1485
1486 /******************************************************************************/
1487 static int
lfreerdp_set_pixel(int pixel,void * bits,int width,int height,int bpp,int delta,int x,int y)1488 lfreerdp_set_pixel(int pixel, void *bits, int width, int height, int bpp,
1489 int delta, int x, int y)
1490 {
1491 tui8 *dst8;
1492 int start;
1493 int shift;
1494
1495 if (bpp == 1)
1496 {
1497 dst8 = (tui8 *)bits;
1498 start = (y * delta) + x / 8;
1499 shift = x % 8;
1500
1501 if (pixel)
1502 {
1503 dst8[start] = dst8[start] | (0x80 >> shift);
1504 }
1505 else
1506 {
1507 dst8[start] = dst8[start] & ~(0x80 >> shift);
1508 }
1509 }
1510 else if (bpp == 24)
1511 {
1512 dst8 = (tui8 *)bits;
1513 dst8 += y * delta + x * 3;
1514 dst8[0] = (pixel >> 0) & 0xff;
1515 dst8[1] = (pixel >> 8) & 0xff;
1516 dst8[2] = (pixel >> 16) & 0xff;
1517 }
1518 else if (bpp == 32)
1519 {
1520 dst8 = (tui8 *)bits;
1521 dst8 += y * delta + x * 4;
1522 ((int *)(dst8))[0] = pixel;
1523 }
1524 else
1525 {
1526 LOG(LOG_LEVEL_WARNING, "lfreerdp_set_pixel: unknown bpp %d", bpp);
1527 }
1528
1529 return 0;
1530 }
1531
1532 /******************************************************************************/
1533 static int
lfreerdp_convert_color_image(void * dst,int dst_width,int dst_height,int dst_bpp,int dst_delta,void * src,int src_width,int src_height,int src_bpp,int src_delta)1534 lfreerdp_convert_color_image(void *dst, int dst_width, int dst_height,
1535 int dst_bpp, int dst_delta,
1536 void *src, int src_width, int src_height,
1537 int src_bpp, int src_delta)
1538 {
1539 int i;
1540 int j;
1541 int pixel;
1542
1543 for (j = 0; j < dst_height; j++)
1544 {
1545 for (i = 0; i < dst_width; i++)
1546 {
1547 pixel = lfreerdp_get_pixel(src, src_width, src_height, src_bpp,
1548 src_delta, i, j);
1549 lfreerdp_set_pixel(pixel, dst, dst_width, dst_height, dst_bpp,
1550 dst_delta, i, j);
1551 }
1552 }
1553
1554 return 0;
1555 }
1556
1557 /******************************************************************************/
1558 static void
lfreerdp_pointer_new(rdpContext * context,POINTER_NEW_UPDATE * pointer_new)1559 lfreerdp_pointer_new(rdpContext *context,
1560 POINTER_NEW_UPDATE *pointer_new)
1561 {
1562 struct mod *mod;
1563 int index;
1564 int bytes_per_pixel;
1565 int bits_per_pixel;
1566 tui8 *dst;
1567 tui8 *src;
1568
1569 mod = ((struct mod_context *)context)->modi;
1570 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_new:");
1571 LOG_DEVEL(LOG_LEVEL_DEBUG, " bpp %d", pointer_new->xorBpp);
1572 LOG_DEVEL(LOG_LEVEL_DEBUG, " width %d height %d", pointer_new->colorPtrAttr.width,
1573 pointer_new->colorPtrAttr.height);
1574
1575 LOG_DEVEL(LOG_LEVEL_DEBUG, " lengthXorMask %d lengthAndMask %d",
1576 pointer_new->colorPtrAttr.lengthXorMask,
1577 pointer_new->colorPtrAttr.lengthAndMask);
1578
1579 index = pointer_new->colorPtrAttr.cacheIndex;
1580
1581 if (index >= 32)
1582 {
1583 LOG(LOG_LEVEL_ERROR, "lfreerdp_pointer_new: pointer index too big");
1584 return ;
1585 }
1586
1587 if (pointer_new->xorBpp == 1 &&
1588 pointer_new->colorPtrAttr.width == 32 &&
1589 pointer_new->colorPtrAttr.height == 32)
1590 {
1591 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_new:");
1592 mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
1593 mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
1594 mod->pointer_cache[index].bpp = 0;
1595 dst = (tui8 *)(mod->pointer_cache[index].data);
1596 dst += 32 * 32 * 3 - 32 * 3;
1597 src = pointer_new->colorPtrAttr.xorMaskData;
1598 lfreerdp_convert_color_image(dst, 32, 32, 24, 32 * -3,
1599 src, 32, 32, 1, 32 / 8);
1600 dst = (tui8 *)(mod->pointer_cache[index].mask);
1601 dst += ( 32 * 32 / 8) - (32 / 8);
1602 src = pointer_new->colorPtrAttr.andMaskData;
1603 lfreerdp_convert_color_image(dst, 32, 32, 1, 32 / -8,
1604 src, 32, 32, 1, 32 / 8);
1605 }
1606 else if (pointer_new->xorBpp >= 8 &&
1607 pointer_new->colorPtrAttr.width == 32 &&
1608 pointer_new->colorPtrAttr.height == 32)
1609 {
1610 bytes_per_pixel = (pointer_new->xorBpp + 7) / 8;
1611 bits_per_pixel = pointer_new->xorBpp;
1612 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_new: bpp %d Bpp %d", bits_per_pixel,
1613 bytes_per_pixel);
1614 mod->pointer_cache[index].hotx = pointer_new->colorPtrAttr.xPos;
1615 mod->pointer_cache[index].hoty = pointer_new->colorPtrAttr.yPos;
1616 mod->pointer_cache[index].bpp = bits_per_pixel;
1617 memcpy(mod->pointer_cache[index].data,
1618 pointer_new->colorPtrAttr.xorMaskData,
1619 32 * 32 * bytes_per_pixel);
1620 memcpy(mod->pointer_cache[index].mask,
1621 pointer_new->colorPtrAttr.andMaskData,
1622 32 * (32 / 8));
1623 }
1624 else
1625 {
1626 LOG(LOG_LEVEL_WARNING, "lfreerdp_pointer_new: error bpp %d width %d height %d index: %d",
1627 pointer_new->xorBpp, pointer_new->colorPtrAttr.width,
1628 pointer_new->colorPtrAttr.height, index);
1629 }
1630
1631 mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
1632 mod->pointer_cache[index].hoty,
1633 mod->pointer_cache[index].data,
1634 mod->pointer_cache[index].mask,
1635 mod->pointer_cache[index].bpp);
1636
1637 free(pointer_new->colorPtrAttr.xorMaskData);
1638 pointer_new->colorPtrAttr.xorMaskData = 0;
1639 free(pointer_new->colorPtrAttr.andMaskData);
1640 pointer_new->colorPtrAttr.andMaskData = 0;
1641
1642 }
1643
1644 /******************************************************************************/
1645 static void
lfreerdp_pointer_cached(rdpContext * context,POINTER_CACHED_UPDATE * pointer_cached)1646 lfreerdp_pointer_cached(rdpContext *context,
1647 POINTER_CACHED_UPDATE *pointer_cached)
1648 {
1649 struct mod *mod;
1650 int index;
1651
1652 mod = ((struct mod_context *)context)->modi;
1653 index = pointer_cached->cacheIndex;
1654 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pointer_cached:%d", index);
1655 mod->server_set_pointer_ex(mod, mod->pointer_cache[index].hotx,
1656 mod->pointer_cache[index].hoty,
1657 mod->pointer_cache[index].data,
1658 mod->pointer_cache[index].mask,
1659 mod->pointer_cache[index].bpp);
1660 }
1661
1662 /******************************************************************************/
1663 static void
lfreerdp_polygon_cb(rdpContext * context,POLYGON_CB_ORDER * polygon_cb)1664 lfreerdp_polygon_cb(rdpContext *context, POLYGON_CB_ORDER *polygon_cb)
1665 {
1666 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_polygon_cb called:- not supported!!!!!!!!!!!!!!!!!!!!");
1667 }
1668
1669 /******************************************************************************/
1670 static void
lfreerdp_polygon_sc(rdpContext * context,POLYGON_SC_ORDER * polygon_sc)1671 lfreerdp_polygon_sc(rdpContext *context, POLYGON_SC_ORDER *polygon_sc)
1672 {
1673 struct mod *mod;
1674 int i;
1675 struct
1676 {
1677 short x, y;
1678 } points[4];
1679 int fgcolor;
1680 int server_bpp, client_bpp;
1681
1682 mod = ((struct mod_context *)context)->modi;
1683 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_polygon_sc :%d(points) %d(color) %d(fillmode) "
1684 "%d(bRop) %d(cbData) %d(x) %d(y)",
1685 polygon_sc->nDeltaEntries, polygon_sc->brushColor,
1686 polygon_sc->fillMode, polygon_sc->bRop2,
1687 polygon_sc->cbData, polygon_sc->xStart,
1688 polygon_sc->yStart);
1689
1690 if (polygon_sc->nDeltaEntries == 3)
1691 {
1692 server_bpp = mod->inst->settings->color_depth;
1693 client_bpp = mod->bpp;
1694
1695 points[0].x = polygon_sc->xStart;
1696 points[0].y = polygon_sc->yStart;
1697
1698 for (i = 0; i < polygon_sc->nDeltaEntries; i++)
1699 {
1700 points[i + 1].x = 0; // polygon_sc->points[i].x;
1701 points[i + 1].y = 0; // polygon_sc->points[i].y;
1702 }
1703
1704 fgcolor = convert_color(server_bpp, client_bpp,
1705 polygon_sc->brushColor, mod->colormap);
1706
1707 mod->server_set_opcode(mod, polygon_sc->bRop2);
1708 mod->server_set_bgcolor(mod, 255);
1709 mod->server_set_fgcolor(mod, fgcolor);
1710 mod->server_set_pen(mod, 1, 1); // style, width
1711 // TODO replace with correct brush; this is a workaround
1712 // This workaround handles the text cursor in microsoft word.
1713 mod->server_draw_line(mod, polygon_sc->xStart, polygon_sc->yStart, polygon_sc->xStart, polygon_sc->yStart + points[2].y);
1714 // mod->server_fill_rect(mod, points[0].x, points[0].y,
1715 // points[0].x-points[3].x, points[0].y-points[2].y);
1716 // mod->server_set_brush(mod,); // howto use this on our indata??
1717 mod->server_set_opcode(mod, 0xcc);
1718 }
1719 else
1720 {
1721 LOG(LOG_LEVEL_WARNING, "Not handled number of points in lfreerdp_polygon_sc");
1722 }
1723 }
1724
1725 /******************************************************************************/
1726 static void
lfreerdp_synchronize(rdpContext * context)1727 lfreerdp_synchronize(rdpContext *context)
1728 {
1729 /* Uncomment these two lines when needed */
1730 #if 0
1731 struct mod *mod;
1732 mod = ((struct mod_context *)context)->modi;
1733 #endif
1734 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_synchronize received - not handled");
1735 }
1736
1737 /******************************************************************************/
1738 static boolean
lfreerdp_pre_connect(freerdp * instance)1739 lfreerdp_pre_connect(freerdp *instance)
1740 {
1741 struct mod *mod;
1742 int index;
1743 int error;
1744 int num_chans;
1745 int ch_flags;
1746 char ch_name[256];
1747 char *dst_ch_name;
1748
1749 LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_pre_connect:");
1750 mod = ((struct mod_context *)(instance->context))->modi;
1751 verifyColorMap(mod);
1752 num_chans = 0;
1753 index = 0;
1754 error = mod->server_query_channel(mod, index, ch_name, &ch_flags);
1755
1756 while (error == 0)
1757 {
1758 num_chans++;
1759 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pre_connect: got channel [%s], id [%d], flags [0x%8.8x]",
1760 ch_name, index, ch_flags);
1761 dst_ch_name = instance->settings->channels[index].name;
1762 g_memset(dst_ch_name, 0, 8);
1763 g_snprintf(dst_ch_name, 8, "%s", ch_name);
1764 instance->settings->channels[index].options = ch_flags;
1765 index++;
1766 error = mod->server_query_channel(mod, index, ch_name, &ch_flags);
1767 }
1768
1769 instance->settings->num_channels = num_chans;
1770
1771 instance->settings->offscreen_bitmap_cache = 0;
1772 instance->settings->draw_nine_grid = 0;
1773
1774 instance->settings->glyph_cache = true;
1775 /* GLYPH_SUPPORT_FULL and GLYPH_SUPPORT_PARTIAL seem to be the same */
1776 /* disabled as workaround for corrupted display like black bars left of cmd with W2K8 */
1777 /* instance->settings->glyphSupportLevel = GLYPH_SUPPORT_FULL; */
1778 instance->settings->glyphSupportLevel = GLYPH_SUPPORT_NONE;
1779
1780 instance->settings->order_support[NEG_DSTBLT_INDEX] = 1; /* 0x00 */
1781 instance->settings->order_support[NEG_PATBLT_INDEX] = 1;
1782 instance->settings->order_support[NEG_SCRBLT_INDEX] = 1;
1783 instance->settings->order_support[NEG_MEMBLT_INDEX] = 1;
1784 instance->settings->order_support[NEG_MEM3BLT_INDEX] = 0;
1785 instance->settings->order_support[NEG_ATEXTOUT_INDEX] = 0;
1786 instance->settings->order_support[NEG_AEXTTEXTOUT_INDEX] = 0;
1787 instance->settings->order_support[NEG_DRAWNINEGRID_INDEX] = 0;
1788 instance->settings->order_support[NEG_LINETO_INDEX] = 1; /* 0x08 */
1789 instance->settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = 0;
1790 instance->settings->order_support[NEG_OPAQUE_RECT_INDEX] = 1;
1791 instance->settings->order_support[NEG_SAVEBITMAP_INDEX] = 0;
1792 instance->settings->order_support[NEG_WTEXTOUT_INDEX] = 0;
1793 instance->settings->order_support[NEG_MEMBLT_V2_INDEX] = 1;
1794 instance->settings->order_support[NEG_MEM3BLT_V2_INDEX] = 0;
1795 instance->settings->order_support[NEG_MULTIDSTBLT_INDEX] = 0;
1796 instance->settings->order_support[NEG_MULTIPATBLT_INDEX] = 0; /* 0x10 */
1797 instance->settings->order_support[NEG_MULTISCRBLT_INDEX] = 0;
1798 instance->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = 0;
1799 instance->settings->order_support[NEG_FAST_INDEX_INDEX] = 0;
1800 instance->settings->order_support[NEG_POLYGON_SC_INDEX] = 0;
1801 instance->settings->order_support[NEG_POLYGON_CB_INDEX] = 0;
1802 instance->settings->order_support[NEG_POLYLINE_INDEX] = 0;
1803 /* 0x17 missing */
1804 instance->settings->order_support[NEG_FAST_GLYPH_INDEX] = 0; /* 0x18 */
1805 instance->settings->order_support[NEG_ELLIPSE_SC_INDEX] = 0;
1806 instance->settings->order_support[NEG_ELLIPSE_CB_INDEX] = 0;
1807 /* disabled as workaround for corrupted display like black bars left of cmd with W2K8 */
1808 /* instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = 1; */
1809 instance->settings->order_support[NEG_GLYPH_INDEX_INDEX] = 0;
1810
1811 instance->settings->order_support[NEG_GLYPH_WEXTTEXTOUT_INDEX] = 0;
1812 instance->settings->order_support[NEG_GLYPH_WLONGTEXTOUT_INDEX] = 0;
1813 instance->settings->order_support[NEG_GLYPH_WLONGEXTTEXTOUT_INDEX] = 0;
1814 /* 0x1F missing*/
1815
1816 instance->settings->bitmap_cache = 1;
1817 instance->settings->bitmapCacheV2NumCells = 3; // 5;
1818 instance->settings->bitmapCacheV2CellInfo[0].numEntries = 600; // 0x78;
1819 instance->settings->bitmapCacheV2CellInfo[0].persistent = 0;
1820 instance->settings->bitmapCacheV2CellInfo[1].numEntries = 600; //0x78; // 600;
1821 instance->settings->bitmapCacheV2CellInfo[1].persistent = 0;
1822 instance->settings->bitmapCacheV2CellInfo[2].numEntries = 2048; //0x150; // 2048;
1823 instance->settings->bitmapCacheV2CellInfo[2].persistent = 0;
1824 instance->settings->bitmapCacheV2CellInfo[3].numEntries = 4096; // 4096;
1825 instance->settings->bitmapCacheV2CellInfo[3].persistent = 0;
1826 instance->settings->bitmapCacheV2CellInfo[4].numEntries = 2048; // 2048;
1827 instance->settings->bitmapCacheV2CellInfo[4].persistent = 0;
1828
1829 instance->settings->bitmap_cache_v3 = 1;
1830
1831 instance->settings->username = g_strdup(mod->username);
1832 instance->settings->password = g_strdup(mod->password);
1833 instance->settings->domain = g_strdup(mod->domain);
1834
1835 if (mod->client_info.rail_enable && (mod->client_info.rail_support_level > 0))
1836 {
1837 LOG_DEVEL(LOG_LEVEL_INFO, "Railsupport !!!!!!!!!!!!!!!!!!");
1838 instance->settings->remote_app = 1;
1839 instance->settings->rail_langbar_supported = 1;
1840 instance->settings->workarea = 1;
1841 instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG;
1842 instance->settings->num_icon_caches = mod->client_info.wnd_num_icon_caches;
1843 instance->settings->num_icon_cache_entries = mod->client_info.wnd_num_icon_cache_entries;
1844
1845
1846 }
1847 else
1848 {
1849 LOG_DEVEL(LOG_LEVEL_DEBUG, "Special PerformanceFlags changed");
1850 instance->settings->performance_flags = PERF_DISABLE_WALLPAPER |
1851 PERF_DISABLE_FULLWINDOWDRAG | PERF_DISABLE_MENUANIMATIONS |
1852 PERF_DISABLE_THEMING;
1853 // | PERF_DISABLE_CURSOR_SHADOW | PERF_DISABLE_CURSORSETTINGS;
1854 }
1855
1856 /* Allow users or administrators to configure the mstsc experience settings. #1903 */
1857
1858 if ((mod->allow_client_experiencesettings == 1) &&
1859 (mod->client_info.mcs_connection_type == CONNECTION_TYPE_AUTODETECT))
1860 {
1861 /* auto-detect not yet supported - use default performance settings */
1862 }
1863 else if (mod->allow_client_experiencesettings == 1)
1864 {
1865 instance->settings->performance_flags =
1866 (mod->client_info.rdp5_performanceflags &
1867 /* Mask to avoid accepting invalid flags. */
1868 (PERF_DISABLE_WALLPAPER |
1869 PERF_DISABLE_FULLWINDOWDRAG |
1870 PERF_DISABLE_MENUANIMATIONS |
1871 PERF_DISABLE_THEMING |
1872 PERF_DISABLE_CURSOR_SHADOW |
1873 PERF_DISABLE_CURSORSETTINGS |
1874 PERF_ENABLE_FONT_SMOOTHING |
1875 PERF_ENABLE_DESKTOP_COMPOSITION));
1876
1877 LOG(LOG_LEVEL_DEBUG, "RDP client experience settings, "
1878 "rdp5_performance_flags:[0x%08x], "
1879 "masked performance_flags:[0x%08x]",
1880 mod->client_info.rdp5_performanceflags,
1881 instance->settings->performance_flags);
1882
1883 if (mod->client_info.rail_enable &&
1884 (mod->client_info.rail_support_level > 0))
1885 {
1886 instance->settings->performance_flags |= (PERF_DISABLE_WALLPAPER |
1887 PERF_DISABLE_FULLWINDOWDRAG);
1888 LOG(LOG_LEVEL_DEBUG, "Add in performance setting for Railsupport:"
1889 "[0x%08x]", PERF_DISABLE_WALLPAPER |
1890 PERF_DISABLE_FULLWINDOWDRAG);
1891 }
1892 }
1893
1894 LOG(LOG_LEVEL_DEBUG, "before overriding performance_flags:[0x%08x]",
1895 instance->settings->performance_flags);
1896 LOG(LOG_LEVEL_DEBUG, "perf_settings_override_mask:[0x%08x], "
1897 "perf_settings_values_mask:[0x%08x]",
1898 mod->perf_settings_override_mask,
1899 mod->perf_settings_values_mask);
1900
1901 /* Clear bits for any overridden performance settings */
1902 instance->settings->performance_flags &= ~mod->perf_settings_override_mask;
1903
1904 /* Add in overridden performance settings */
1905 instance->settings->performance_flags |= mod->perf_settings_values_mask;
1906
1907 LOG(LOG_LEVEL_DEBUG, "final performance_flags:[0x%08x]",
1908 instance->settings->performance_flags);
1909
1910 instance->settings->compression = 0;
1911 instance->settings->ignore_certificate = 1;
1912
1913 // Multi Monitor Settings
1914 instance->settings->num_monitors = mod->client_info.monitorCount;
1915
1916 for (index = 0; index < mod->client_info.monitorCount; index++)
1917 {
1918 instance->settings->monitors[index].x = mod->client_info.minfo[index].left;
1919 instance->settings->monitors[index].y = mod->client_info.minfo[index].top;
1920 instance->settings->monitors[index].width = mod->client_info.minfo[index].right;
1921 instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom;
1922 instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary;
1923 }
1924
1925 instance->update->BeginPaint = lfreerdp_begin_paint;
1926 instance->update->EndPaint = lfreerdp_end_paint;
1927 instance->update->SetBounds = lfreerdp_set_bounds;
1928 instance->update->BitmapUpdate = lfreerdp_bitmap_update;
1929 instance->update->Synchronize = lfreerdp_synchronize;
1930 instance->update->primary->DstBlt = lfreerdp_dst_blt;
1931 instance->update->primary->PatBlt = lfreerdp_pat_blt;
1932 instance->update->primary->ScrBlt = lfreerdp_scr_blt;
1933 instance->update->primary->OpaqueRect = lfreerdp_opaque_rect;
1934 instance->update->primary->MemBlt = lfreerdp_mem_blt;
1935 instance->update->primary->GlyphIndex = lfreerdp_glyph_index;
1936 instance->update->primary->LineTo = lfreerdp_line_to;
1937 instance->update->primary->PolygonSC = lfreerdp_polygon_sc ;
1938 instance->update->primary->PolygonCB = lfreerdp_polygon_cb;
1939 instance->update->secondary->CacheBitmap = lfreerdp_cache_bitmap;
1940 instance->update->secondary->CacheBitmapV2 = lfreerdp_cache_bitmapV2;
1941 instance->update->secondary->CacheGlyph = lfreerdp_cache_glyph;
1942 instance->update->secondary->CacheBrush = lfreerdp_cache_brush;
1943
1944 instance->update->pointer->PointerPosition = lfreerdp_pointer_position;
1945 instance->update->pointer->PointerSystem = lfreerdp_pointer_system;
1946 instance->update->pointer->PointerColor = lfreerdp_pointer_color;
1947 instance->update->pointer->PointerNew = lfreerdp_pointer_new;
1948 instance->update->pointer->PointerCached = lfreerdp_pointer_cached;
1949
1950 if ((mod->username[0] != 0) && (mod->password[0] != 0))
1951 {
1952 /* since we have username and password, we can try nla */
1953 instance->settings->nla_security = 1;
1954 }
1955 else
1956 {
1957 instance->settings->nla_security = 0;
1958 }
1959
1960 return 1;
1961 }
1962
1963 /*****************************************************************************/
1964 void
lrail_WindowCreate(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,WINDOW_STATE_ORDER * window_state)1965 lrail_WindowCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
1966 WINDOW_STATE_ORDER *window_state)
1967 {
1968 int index;
1969 struct mod *mod;
1970 struct rail_window_state_order wso;
1971 UNICONV *uniconv;
1972
1973 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowCreate:");
1974 uniconv = freerdp_uniconv_new();
1975 mod = ((struct mod_context *)context)->modi;
1976 memset(&wso, 0, sizeof(wso));
1977 /* copy the window state order */
1978 wso.owner_window_id = window_state->ownerWindowId;
1979 wso.style = window_state->style;
1980 wso.extended_style = window_state->extendedStyle;
1981 wso.show_state = window_state->showState;
1982
1983 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_TITLE)
1984 {
1985 wso.title_info = freerdp_uniconv_in(uniconv,
1986 window_state->titleInfo.string, window_state->titleInfo.length);
1987 }
1988
1989 LOG_DEVEL(LOG_LEVEL_DEBUG, "lrail_WindowCreate: %s", wso.title_info);
1990 wso.client_offset_x = window_state->clientOffsetX;
1991 wso.client_offset_y = window_state->clientOffsetY;
1992 wso.client_area_width = window_state->clientAreaWidth;
1993 wso.client_area_height = window_state->clientAreaHeight;
1994 wso.rp_content = window_state->RPContent;
1995 wso.root_parent_handle = window_state->rootParentHandle;
1996 wso.window_offset_x = window_state->windowOffsetX;
1997 wso.window_offset_y = window_state->windowOffsetY;
1998 wso.window_client_delta_x = window_state->windowClientDeltaX;
1999 wso.window_client_delta_y = window_state->windowClientDeltaY;
2000 wso.window_width = window_state->windowWidth;
2001 wso.window_height = window_state->windowHeight;
2002 wso.num_window_rects = window_state->numWindowRects;
2003
2004 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS)
2005 {
2006 wso.window_rects = (struct rail_window_rect *)
2007 g_malloc(sizeof(struct rail_window_rect) * wso.num_window_rects, 0);
2008
2009 for (index = 0; index < wso.num_window_rects; index++)
2010 {
2011 wso.window_rects[index].left = window_state->windowRects[index].left;
2012 wso.window_rects[index].top = window_state->windowRects[index].top;
2013 wso.window_rects[index].right = window_state->windowRects[index].right;
2014 wso.window_rects[index].bottom = window_state->windowRects[index].bottom;
2015 }
2016 }
2017
2018 wso.visible_offset_x = window_state->visibleOffsetX;
2019 wso.visible_offset_y = window_state->visibleOffsetY;
2020 wso.num_visibility_rects = window_state->numVisibilityRects;
2021
2022 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)
2023 {
2024 wso.visibility_rects = (struct rail_window_rect *)
2025 g_malloc(sizeof(struct rail_window_rect) * wso.num_visibility_rects, 0);
2026
2027 for (index = 0; index < wso.num_visibility_rects; index++)
2028 {
2029 wso.visibility_rects[index].left = window_state->visibilityRects[index].left;
2030 wso.visibility_rects[index].top = window_state->visibilityRects[index].top;
2031 wso.visibility_rects[index].right = window_state->visibilityRects[index].right;
2032 wso.visibility_rects[index].bottom = window_state->visibilityRects[index].bottom;
2033 }
2034 }
2035
2036 mod->server_window_new_update(mod, orderInfo->windowId, &wso,
2037 orderInfo->fieldFlags);
2038
2039 free(wso.title_info);
2040 g_free(wso.window_rects);
2041 g_free(wso.visibility_rects);
2042 }
2043
2044 /*****************************************************************************/
2045 void
lrail_WindowUpdate(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,WINDOW_STATE_ORDER * window_state)2046 lrail_WindowUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
2047 WINDOW_STATE_ORDER *window_state)
2048 {
2049 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowUpdate:");
2050 lrail_WindowCreate(context, orderInfo, window_state);
2051 }
2052
2053 /*****************************************************************************/
2054 void
lrail_WindowDelete(rdpContext * context,WINDOW_ORDER_INFO * orderInfo)2055 lrail_WindowDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
2056 {
2057 struct mod *mod;
2058
2059 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowDelete:");
2060 mod = ((struct mod_context *)context)->modi;
2061 mod->server_window_delete(mod, orderInfo->windowId);
2062 }
2063
2064 /*****************************************************************************/
2065 void
lrail_WindowIcon(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,WINDOW_ICON_ORDER * window_icon)2066 lrail_WindowIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
2067 WINDOW_ICON_ORDER *window_icon)
2068 {
2069 struct mod *mod;
2070 struct rail_icon_info rii;
2071
2072 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowIcon:");
2073 mod = ((struct mod_context *)context)->modi;
2074 memset(&rii, 0, sizeof(rii));
2075 rii.bpp = window_icon->iconInfo->bpp;
2076 rii.width = window_icon->iconInfo->width;
2077 rii.height = window_icon->iconInfo->height;
2078 rii.cmap_bytes = window_icon->iconInfo->cbColorTable;
2079 rii.mask_bytes = window_icon->iconInfo->cbBitsMask;
2080 rii.data_bytes = window_icon->iconInfo->cbBitsColor;
2081 rii.mask = (char *)(window_icon->iconInfo->bitsMask);
2082 rii.cmap = (char *)(window_icon->iconInfo->colorTable);
2083 rii.data = (char *)(window_icon->iconInfo->bitsColor);
2084 mod->server_window_icon(mod, orderInfo->windowId,
2085 window_icon->iconInfo->cacheEntry,
2086 window_icon->iconInfo->cacheId, &rii,
2087 orderInfo->fieldFlags);
2088 }
2089
2090 /*****************************************************************************/
2091 void
lrail_WindowCachedIcon(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,WINDOW_CACHED_ICON_ORDER * window_cached_icon)2092 lrail_WindowCachedIcon(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
2093 WINDOW_CACHED_ICON_ORDER *window_cached_icon)
2094 {
2095 struct mod *mod;
2096
2097 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_WindowCachedIcon:");
2098 mod = ((struct mod_context *)context)->modi;
2099 mod->server_window_cached_icon(mod, orderInfo->windowId,
2100 window_cached_icon->cachedIcon.cacheEntry,
2101 window_cached_icon->cachedIcon.cacheId,
2102 orderInfo->fieldFlags);
2103 }
2104
2105 /*****************************************************************************/
2106 void
lrail_NotifyIconCreate(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,NOTIFY_ICON_STATE_ORDER * notify_icon_state)2107 lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
2108 NOTIFY_ICON_STATE_ORDER *notify_icon_state)
2109 {
2110 struct mod *mod;
2111 struct rail_notify_state_order rnso;
2112 UNICONV *uniconv;
2113
2114 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_NotifyIconCreate:");
2115 uniconv = freerdp_uniconv_new();
2116 mod = ((struct mod_context *)context)->modi;
2117
2118 memset(&rnso, 0, sizeof(rnso));
2119 rnso.version = notify_icon_state->version;
2120
2121 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP)
2122 {
2123 rnso.tool_tip = freerdp_uniconv_in(uniconv,
2124 notify_icon_state->toolTip.string, notify_icon_state->toolTip.length);
2125 }
2126
2127 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP)
2128 {
2129 rnso.infotip.timeout = notify_icon_state->infoTip.timeout;
2130 rnso.infotip.flags = notify_icon_state->infoTip.flags;
2131 rnso.infotip.text = freerdp_uniconv_in(uniconv,
2132 notify_icon_state->infoTip.text.string,
2133 notify_icon_state->infoTip.text.length);
2134 rnso.infotip.title = freerdp_uniconv_in(uniconv,
2135 notify_icon_state->infoTip.title.string,
2136 notify_icon_state->infoTip.title.length);
2137 }
2138
2139 rnso.state = notify_icon_state->state;
2140 rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry;
2141 rnso.icon_cache_id = notify_icon_state->icon.cacheId;
2142
2143 rnso.icon_info.bpp = notify_icon_state->icon.bpp;
2144 rnso.icon_info.width = notify_icon_state->icon.width;
2145 rnso.icon_info.height = notify_icon_state->icon.height;
2146 rnso.icon_info.cmap_bytes = notify_icon_state->icon.cbColorTable;
2147 rnso.icon_info.mask_bytes = notify_icon_state->icon.cbBitsMask;
2148 rnso.icon_info.data_bytes = notify_icon_state->icon.cbBitsColor;
2149 rnso.icon_info.mask = (char *)(notify_icon_state->icon.bitsMask);
2150 rnso.icon_info.cmap = (char *)(notify_icon_state->icon.colorTable);
2151 rnso.icon_info.data = (char *)(notify_icon_state->icon.bitsColor);
2152
2153 mod->server_notify_new_update(mod, orderInfo->windowId,
2154 orderInfo->notifyIconId,
2155 &rnso, orderInfo->fieldFlags);
2156
2157 free(rnso.tool_tip);
2158 free(rnso.infotip.text);
2159 free(rnso.infotip.title);
2160 }
2161
2162 /*****************************************************************************/
2163 void
lrail_NotifyIconUpdate(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,NOTIFY_ICON_STATE_ORDER * notify_icon_state)2164 lrail_NotifyIconUpdate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
2165 NOTIFY_ICON_STATE_ORDER *notify_icon_state)
2166 {
2167 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_NotifyIconUpdate:");
2168 lrail_NotifyIconCreate(context, orderInfo, notify_icon_state);
2169 }
2170
2171 /*****************************************************************************/
2172 void
lrail_NotifyIconDelete(rdpContext * context,WINDOW_ORDER_INFO * orderInfo)2173 lrail_NotifyIconDelete(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
2174 {
2175 struct mod *mod;
2176
2177 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_NotifyIconDelete:");
2178 mod = ((struct mod_context *)context)->modi;
2179 mod->server_notify_delete(mod, orderInfo->windowId,
2180 orderInfo->notifyIconId);
2181 }
2182
2183 /*****************************************************************************/
2184 void
lrail_MonitoredDesktop(rdpContext * context,WINDOW_ORDER_INFO * orderInfo,MONITORED_DESKTOP_ORDER * monitored_desktop)2185 lrail_MonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo,
2186 MONITORED_DESKTOP_ORDER *monitored_desktop)
2187 {
2188 int index;
2189 struct mod *mod;
2190 struct rail_monitored_desktop_order rmdo;
2191
2192 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_MonitoredDesktop:");
2193 mod = ((struct mod_context *)context)->modi;
2194 memset(&rmdo, 0, sizeof(rmdo));
2195 rmdo.active_window_id = monitored_desktop->activeWindowId;
2196 rmdo.num_window_ids = monitored_desktop->numWindowIds;
2197
2198 if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER)
2199 {
2200 if (rmdo.num_window_ids > 0)
2201 {
2202 rmdo.window_ids = (int *)g_malloc(sizeof(int) * rmdo.num_window_ids, 0);
2203
2204 for (index = 0; index < rmdo.num_window_ids; index++)
2205 {
2206 rmdo.window_ids[index] = monitored_desktop->windowIds[index];
2207 }
2208 }
2209 }
2210
2211 mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
2212 g_free(rmdo.window_ids);
2213 }
2214
2215 /*****************************************************************************/
2216 void
lrail_NonMonitoredDesktop(rdpContext * context,WINDOW_ORDER_INFO * orderInfo)2217 lrail_NonMonitoredDesktop(rdpContext *context, WINDOW_ORDER_INFO *orderInfo)
2218 {
2219 struct mod *mod;
2220 struct rail_monitored_desktop_order rmdo;
2221
2222 LOG_DEVEL(LOG_LEVEL_TRACE, "lrail_NonMonitoredDesktop:");
2223 mod = ((struct mod_context *)context)->modi;
2224 memset(&rmdo, 0, sizeof(rmdo));
2225 mod->server_monitored_desktop(mod, &rmdo, orderInfo->fieldFlags);
2226 }
2227
2228 /******************************************************************************/
2229 static boolean
lfreerdp_post_connect(freerdp * instance)2230 lfreerdp_post_connect(freerdp *instance)
2231 {
2232 struct mod *mod;
2233
2234 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_post_connect:");
2235 mod = ((struct mod_context *)(instance->context))->modi;
2236 g_memset(mod->password, 0, sizeof(mod->password));
2237
2238 mod->inst->update->window->WindowCreate = lrail_WindowCreate;
2239 mod->inst->update->window->WindowUpdate = lrail_WindowUpdate;
2240 mod->inst->update->window->WindowDelete = lrail_WindowDelete;
2241 mod->inst->update->window->WindowIcon = lrail_WindowIcon;
2242 mod->inst->update->window->WindowCachedIcon = lrail_WindowCachedIcon;
2243 mod->inst->update->window->NotifyIconCreate = lrail_NotifyIconCreate;
2244 mod->inst->update->window->NotifyIconUpdate = lrail_NotifyIconUpdate;
2245 mod->inst->update->window->NotifyIconDelete = lrail_NotifyIconDelete;
2246 mod->inst->update->window->MonitoredDesktop = lrail_MonitoredDesktop;
2247 mod->inst->update->window->NonMonitoredDesktop = lrail_NonMonitoredDesktop;
2248
2249 return 1;
2250 }
2251
2252 /******************************************************************************/
2253 static void
lfreerdp_context_new(freerdp * instance,rdpContext * context)2254 lfreerdp_context_new(freerdp *instance, rdpContext *context)
2255 {
2256 LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_context_new: %p", context);
2257 }
2258
2259 /******************************************************************************/
2260 static void
lfreerdp_context_free(freerdp * instance,rdpContext * context)2261 lfreerdp_context_free(freerdp *instance, rdpContext *context)
2262 {
2263 LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_context_free: - no code here");
2264 }
2265
2266 /******************************************************************************/
2267 static int
lfreerdp_receive_channel_data(freerdp * instance,int channelId,uint8 * data,int size,int flags,int total_size)2268 lfreerdp_receive_channel_data(freerdp *instance, int channelId, uint8 *data,
2269 int size, int flags, int total_size)
2270 {
2271 struct mod *mod;
2272 int lchid;
2273 int index;
2274 int error;
2275
2276 mod = ((struct mod_context *)(instance->context))->modi;
2277 lchid = -1;
2278
2279 for (index = 0; index < instance->settings->num_channels; index++)
2280 {
2281 if (instance->settings->channels[index].channel_id == channelId)
2282 {
2283 lchid = index;
2284 break;
2285 }
2286 }
2287
2288 if (lchid >= 0)
2289 {
2290 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_receive_channel_data: server to client, chanid: %d", lchid);
2291 error = mod->server_send_to_channel(mod, lchid, (char *)data, size,
2292 total_size, flags);
2293
2294 if (error != 0)
2295 {
2296 LOG(LOG_LEVEL_ERROR, "lfreerdp_receive_channel_data: error %d", error);
2297 }
2298 }
2299 else
2300 {
2301 LOG(LOG_LEVEL_ERROR, "lfreerdp_receive_channel_data: bad lchid");
2302 }
2303
2304 return 0;
2305 }
2306
2307 /******************************************************************************/
2308 static boolean
lfreerdp_authenticate(freerdp * instance,char ** username,char ** password,char ** domain)2309 lfreerdp_authenticate(freerdp *instance, char **username,
2310 char **password, char **domain)
2311 {
2312 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_authenticate: - no code here");
2313 return 1;
2314 }
2315
2316 /******************************************************************************/
2317 static boolean
lfreerdp_verify_certificate(freerdp * instance,char * subject,char * issuer,char * fingerprint)2318 lfreerdp_verify_certificate(freerdp *instance, char *subject, char *issuer,
2319 char *fingerprint)
2320 {
2321 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_verify_certificate: - no code here");
2322 return 1;
2323 }
2324
2325 /******************************************************************************/
2326 static int
lfreerdp_session_info(freerdp * instance,uint8 * data,int data_bytes)2327 lfreerdp_session_info(freerdp *instance, uint8 *data, int data_bytes)
2328 {
2329 struct mod *mod;
2330 int error;
2331
2332 LOG_DEVEL(LOG_LEVEL_TRACE, "lfreerdp_session_info:");
2333 error = 0;
2334 mod = ((struct mod_context *)(instance->context))->modi;
2335 if (mod != 0)
2336 {
2337 LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_session_info: mod->server_session_info %p",
2338 mod->server_session_info);
2339 if (mod->server_session_info != 0)
2340 {
2341 error = mod->server_session_info(mod, (char *)data, data_bytes);
2342 }
2343 }
2344 return error;
2345 }
2346
2347 /******************************************************************************/
2348 tintptr EXPORT_CC
mod_init(void)2349 mod_init(void)
2350 {
2351 struct mod *mod;
2352 modContext *lcon;
2353
2354 LOG_DEVEL(LOG_LEVEL_TRACE, "mod_init:");
2355 mod = (struct mod *)g_malloc(sizeof(struct mod), 1);
2356 freerdp_get_version(&(mod->vmaj), &(mod->vmin), &(mod->vrev));
2357 LOG(LOG_LEVEL_INFO, " FreeRDP version major %d minor %d revision %d",
2358 mod->vmaj, mod->vmin, mod->vrev);
2359 mod->size = sizeof(struct mod);
2360 mod->version = CURRENT_MOD_VER;
2361 mod->handle = (tintptr) mod;
2362 mod->mod_connect = lxrdp_connect;
2363 mod->mod_start = lxrdp_start;
2364 mod->mod_event = lxrdp_event;
2365 mod->mod_signal = lxrdp_signal;
2366 mod->mod_end = lxrdp_end;
2367 mod->mod_set_param = lxrdp_set_param;
2368 mod->mod_session_change = lxrdp_session_change;
2369 mod->mod_get_wait_objs = lxrdp_get_wait_objs;
2370 mod->mod_check_wait_objs = lxrdp_check_wait_objs;
2371 mod->mod_frame_ack = lxrdp_frame_ack;
2372 mod->mod_suppress_output = lxrdp_suppress_output;
2373 mod->mod_server_version_message = lxrdp_server_version_message;
2374 mod->mod_server_monitor_resize = lxrdp_server_monitor_resize;
2375 mod->mod_server_monitor_full_invalidate = lxrdp_server_monitor_full_invalidate;
2376
2377 mod->inst = freerdp_new();
2378 mod->inst->PreConnect = lfreerdp_pre_connect;
2379 mod->inst->PostConnect = lfreerdp_post_connect;
2380 mod->inst->context_size = sizeof(modContext);
2381 mod->inst->ContextNew = lfreerdp_context_new;
2382 mod->inst->ContextFree = lfreerdp_context_free;
2383 mod->inst->ReceiveChannelData = lfreerdp_receive_channel_data;
2384 mod->inst->Authenticate = lfreerdp_authenticate;
2385 mod->inst->VerifyCertificate = lfreerdp_verify_certificate;
2386 #if defined(VERSION_STRUCT_RDP_FREERDP)
2387 #if VERSION_STRUCT_RDP_FREERDP > 0
2388 mod->inst->SessionInfo = lfreerdp_session_info;
2389 #endif
2390 #endif
2391
2392 freerdp_context_new(mod->inst);
2393
2394 lcon = (modContext *)(mod->inst->context);
2395 lcon->modi = mod;
2396 LOG_DEVEL(LOG_LEVEL_DEBUG, "mod_init: mod %p", mod);
2397
2398 return (tintptr) mod;
2399 }
2400
2401 /******************************************************************************/
2402 int EXPORT_CC
mod_exit(tintptr handle)2403 mod_exit(tintptr handle)
2404 {
2405 struct mod *mod = (struct mod *) handle;
2406
2407 LOG_DEVEL(LOG_LEVEL_TRACE, "mod_exit:");
2408
2409 if (mod == 0)
2410 {
2411 return 0;
2412 }
2413
2414 if (mod->inst == NULL)
2415 {
2416 LOG(LOG_LEVEL_ERROR, "mod_exit - null pointer for inst:");
2417 g_free(mod);
2418 return 0 ;
2419 }
2420
2421 freerdp_disconnect(mod->inst);
2422
2423 if ((mod->vmaj == 1) && (mod->vmin == 0) && (mod->vrev == 1))
2424 {
2425 /* this version has a bug with double free in freerdp_free */
2426 }
2427 else
2428 {
2429 freerdp_context_free(mod->inst);
2430 }
2431
2432 freerdp_free(mod->inst);
2433 g_free(mod);
2434 return 0;
2435 }
2436