1 /**
2 * xrdp: A Remote Desktop Protocol server.
3 *
4 * Copyright (C) Jay Sorg 2004-2013
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * this is the interface to libxrdp
19 */
20
21 #if defined(HAVE_CONFIG_H)
22 #include <config_ac.h>
23 #endif
24
25 #include "libxrdp.h"
26 #include "string_calls.h"
27 #include "xrdp_orders_rail.h"
28
29 #include "ms-rdpbcgr.h"
30
31
32
33 #define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
34
35 /******************************************************************************/
36 struct xrdp_session *EXPORT_CC
libxrdp_init(tbus id,struct trans * trans,const char * xrdp_ini)37 libxrdp_init(tbus id, struct trans *trans, const char *xrdp_ini)
38 {
39 struct xrdp_session *session;
40
41 session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1);
42 session->id = id;
43 session->trans = trans;
44 if (xrdp_ini != NULL)
45 {
46 session->xrdp_ini = g_strdup(xrdp_ini);
47 }
48 else
49 {
50 session->xrdp_ini = g_strdup(XRDP_CFG_PATH "/xrdp.ini");
51 }
52 session->rdp = xrdp_rdp_create(session, trans);
53 session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp);
54 session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info);
55 session->check_for_app_input = 1;
56 return session;
57 }
58
59 /******************************************************************************/
60 int EXPORT_CC
libxrdp_exit(struct xrdp_session * session)61 libxrdp_exit(struct xrdp_session *session)
62 {
63 if (session == 0)
64 {
65 return 0;
66 }
67
68 xrdp_orders_delete((struct xrdp_orders *)session->orders);
69 xrdp_rdp_delete((struct xrdp_rdp *)session->rdp);
70 g_free(session->xrdp_ini);
71 g_free(session);
72 return 0;
73 }
74
75 /******************************************************************************/
76 int EXPORT_CC
libxrdp_disconnect(struct xrdp_session * session)77 libxrdp_disconnect(struct xrdp_session *session)
78 {
79 return xrdp_rdp_disconnect((struct xrdp_rdp *)session->rdp);
80 }
81
82 /******************************************************************************/
83 int EXPORT_CC
libxrdp_process_incoming(struct xrdp_session * session)84 libxrdp_process_incoming(struct xrdp_session *session)
85 {
86 int rv;
87
88 rv = xrdp_rdp_incoming((struct xrdp_rdp *)(session->rdp));
89 return rv;
90 }
91
92 /*****************************************************************************/
93 int EXPORT_CC
libxrdp_get_pdu_bytes(const char * aheader)94 libxrdp_get_pdu_bytes(const char *aheader)
95 {
96 int rv;
97 const tui8 *header;
98
99 rv = -1;
100 header = (const tui8 *) aheader;
101
102 if (header[0] == 0x03)
103 {
104 /* TPKT */
105 rv = (header[2] << 8) | header[3];
106 }
107 else
108 {
109 /* Fast-Path */
110 if (header[1] & 0x80)
111 {
112 rv = ((header[1] & 0x7F) << 8) | header[2];
113 }
114 else
115 {
116 rv = header[1];
117 }
118 }
119 return rv;
120 }
121
122 /******************************************************************************/
123 /* only used during connection */
124 struct stream *
libxrdp_force_read(struct trans * trans)125 libxrdp_force_read(struct trans *trans)
126 {
127 int bytes;
128 struct stream *s;
129
130 s = trans->in_s;
131 init_stream(s, 32 * 1024);
132
133 if (trans_force_read(trans, 4) != 0)
134 {
135 LOG(LOG_LEVEL_ERROR, "libxrdp_force_read: header read error");
136 return NULL;
137 }
138 bytes = libxrdp_get_pdu_bytes(s->data);
139 if (bytes < 4 || bytes > s->size)
140 {
141 LOG(LOG_LEVEL_ERROR, "libxrdp_force_read: bad header length %d", bytes);
142 return NULL;
143 }
144 if (trans_force_read(trans, bytes - 4) != 0)
145 {
146 LOG(LOG_LEVEL_ERROR, "libxrdp_force_read: Can't read PDU");
147 return NULL;
148 }
149 return s;
150 }
151
152 /******************************************************************************/
153 int EXPORT_CC
libxrdp_process_data(struct xrdp_session * session,struct stream * s)154 libxrdp_process_data(struct xrdp_session *session, struct stream *s)
155 {
156 int cont;
157 int rv;
158 int code;
159 int term;
160 int dead_lock_counter;
161 int do_read;
162 struct xrdp_rdp *rdp;
163
164 do_read = s == 0;
165 if (do_read && session->up_and_running)
166 {
167 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error logic");
168 return 1;
169 }
170 if (session->in_process_data != 0)
171 {
172 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: error reentry");
173 return 1;
174 }
175 session->in_process_data++;
176
177 term = 0;
178 cont = 1;
179 rv = 0;
180 dead_lock_counter = 0;
181
182 rdp = (struct xrdp_rdp *) (session->rdp);
183
184 while ((cont || !session->up_and_running) && !term)
185 {
186 if (session->is_term != 0)
187 {
188 if (session->is_term())
189 {
190 term = 1;
191 break;
192 }
193 }
194
195 code = 0;
196
197 if (do_read)
198 {
199 if (s == 0)
200 {
201 s = libxrdp_force_read(session->trans);
202 }
203 else
204 {
205 if ((s->next_packet == 0) || (s->next_packet >= s->end))
206 {
207 s = libxrdp_force_read(session->trans);
208 }
209 }
210 if (s == 0)
211 {
212 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: libxrdp_force_read failed");
213 rv = 1;
214 break;
215 }
216 }
217
218 if (xrdp_rdp_recv(rdp, s, &code) != 0)
219 {
220 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_rdp_recv failed");
221 rv = 1;
222 break;
223 }
224
225 LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_data code %d", code);
226
227 switch (code)
228 {
229 case -1:
230 xrdp_caps_send_demand_active(rdp);
231 session->up_and_running = 0;
232 break;
233 case 0:
234 dead_lock_counter++;
235 break;
236 case PDUTYPE_CONFIRMACTIVEPDU:
237 LOG_DEVEL(LOG_LEVEL_TRACE, "Processing received "
238 "[MS-RDPBCGR] PDUTYPE_CONFIRMACTIVEPDU");
239 xrdp_caps_process_confirm_active(rdp, s);
240 break;
241 case PDUTYPE_DATAPDU:
242 LOG_DEVEL(LOG_LEVEL_TRACE, "Processing received "
243 "[MS-RDPBCGR] PDUTYPE_DATAPDU");
244 if (xrdp_rdp_process_data(rdp, s) != 0)
245 {
246 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_rdp_process_data failed");
247 cont = 0;
248 term = 1;
249 }
250 break;
251 case 2: /* FASTPATH_INPUT_EVENT */
252 if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0)
253 {
254 LOG(LOG_LEVEL_ERROR, "libxrdp_process_data: xrdp_fastpath_process_input_event failed");
255 cont = 0;
256 term = 1;
257 }
258 break;
259 default:
260 LOG(LOG_LEVEL_WARNING, "unknown code = %d (ignored)", code);
261 dead_lock_counter++;
262 break;
263 }
264
265 if (dead_lock_counter > 100000)
266 {
267 /*This situation can happen and this is a workaround*/
268 cont = 0;
269 LOG(LOG_LEVEL_WARNING,
270 "Serious programming error: we were locked in a deadly loop. "
271 "Remaining bytes: %d", (int) (s->end - s->next_packet));
272 s->next_packet = 0;
273 }
274
275 if (cont)
276 {
277 cont = (s->next_packet != 0) && (s->next_packet < s->end);
278 }
279 }
280
281 session->in_process_data--;
282
283 return rv;
284 }
285
286 /******************************************************************************/
287 int EXPORT_CC
libxrdp_send_palette(struct xrdp_session * session,int * palette)288 libxrdp_send_palette(struct xrdp_session *session, int *palette)
289 {
290 int rv;
291 int i = 0;
292 int color = 0;
293 struct stream *s = (struct stream *)NULL;
294
295 if (session->client_info->bpp > 8)
296 {
297 return 0;
298 }
299
300 LOG_DEVEL(LOG_LEVEL_DEBUG, "sending palette (%s)",
301 ((session->client_info->use_fast_path & 1) ?
302 "fastpath" : "slowpath"));
303
304 /* clear orders */
305 libxrdp_orders_force_send(session);
306 make_stream(s);
307 init_stream(s, 8192);
308
309 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
310 {
311 if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
312 {
313 LOG(LOG_LEVEL_ERROR, "libxrdp_send_palette: xrdp_rdp_init_fastpath failed");
314 free_stream(s);
315 return 1;
316 }
317 }
318 else
319 {
320 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
321 }
322
323 /* TS_UPDATE_PALETTE_DATA */
324 out_uint16_le(s, RDP_UPDATE_PALETTE); /* updateType */
325 out_uint16_le(s, 0); /* pad2Octets */
326 out_uint16_le(s, 256); /* # of colors (low-bytes) */
327 out_uint16_le(s, 0); /* # of colors (high-bytes) */
328
329 /* paletteEntries */
330 for (i = 0; i < 256; i++)
331 {
332 color = palette[i];
333 out_uint8(s, color >> 16);
334 out_uint8(s, color >> 8);
335 out_uint8(s, color);
336 }
337
338 s_mark_end(s);
339 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
340 {
341 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_UPDATE_PALETTE "
342 "paletteUpdateData = { updateType %d (UPDATETYPE_PALETTE), "
343 "pad2Octets <ignored>, numberColors 256, "
344 "paletteEntries <omitted from log> }", RDP_UPDATE_PALETTE);
345 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
346 FASTPATH_UPDATETYPE_PALETTE) != 0)
347 {
348 LOG(LOG_LEVEL_ERROR, "libxrdp_send_palette: xrdp_rdp_send_fastpath failed");
349 free_stream(s);
350 return 1;
351 }
352 }
353 else
354 {
355 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_PALETTE_DATA "
356 "updateType %d (UPDATETYPE_PALETTE), pad2Octets <ignored>, "
357 "numberColors 256, paletteEntries <omitted from log>",
358 RDP_UPDATE_PALETTE);
359 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
360 RDP_DATA_PDU_UPDATE);
361 }
362 free_stream(s);
363
364 /* send the orders palette too */
365 rv = libxrdp_orders_init(session);
366 if (rv == 0)
367 {
368 rv = libxrdp_orders_send_palette(session, palette, 0);
369 }
370 if (rv == 0)
371 {
372 rv = libxrdp_orders_send(session);
373 }
374 return rv;
375 }
376
377 /******************************************************************************/
378 int EXPORT_CC
libxrdp_send_bell(struct xrdp_session * session)379 libxrdp_send_bell(struct xrdp_session *session)
380 {
381 struct stream *s = (struct stream *)NULL;
382
383 make_stream(s);
384 init_stream(s, 8192);
385
386 if (xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s) != 0)
387 {
388 LOG(LOG_LEVEL_ERROR, "libxrdp_send_bell: xrdp_rdp_init_data failed");
389 free_stream(s);
390 return 1;
391 }
392
393 out_uint32_le(s, 100); /* duration (ms) */
394 out_uint32_le(s, 440); /* frequency */
395 s_mark_end(s);
396 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_PLAY_SOUND_PDU_DATA "
397 "duration 100 ms, frequency 440 Hz");
398
399 if (xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0)
400 {
401 LOG(LOG_LEVEL_ERROR, "libxrdp_send_bell: xrdp_rdp_send_data failed");
402 free_stream(s);
403 return 1;
404 }
405
406 free_stream(s);
407 return 0;
408 }
409
410 /*****************************************************************************/
411 int EXPORT_CC
libxrdp_send_bitmap(struct xrdp_session * session,int width,int height,int bpp,char * data,int x,int y,int cx,int cy)412 libxrdp_send_bitmap(struct xrdp_session *session, int width, int height,
413 int bpp, char *data, int x, int y, int cx, int cy)
414 {
415 int line_bytes = 0;
416 int i = 0;
417 int j = 0;
418 int k;
419 int total_lines = 0;
420 int lines_sending = 0;
421 int Bpp = 0;
422 int e = 0;
423 int bufsize = 0;
424 int total_bufsize = 0;
425 int num_updates = 0;
426 int line_pad_bytes;
427 int server_line_bytes;
428 char *p_num_updates = (char *)NULL;
429 char *p = (char *)NULL;
430 char *q = (char *)NULL;
431 struct stream *s = (struct stream *)NULL;
432 struct stream *temp_s = (struct stream *)NULL;
433 tui32 pixel;
434
435 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: sending bitmap");
436 Bpp = (bpp + 7) / 8;
437 e = (4 - width) & 3;
438 switch (bpp)
439 {
440 case 15:
441 case 16:
442 server_line_bytes = width * 2;
443 break;
444 case 24:
445 case 32:
446 server_line_bytes = width * 4;
447 break;
448 default: /* 8 bpp */
449 server_line_bytes = width;
450 break;
451 }
452 line_bytes = width * Bpp;
453 line_pad_bytes = line_bytes + e * Bpp;
454
455 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: bpp %d Bpp %d line_bytes %d "
456 "server_line_bytes %d", bpp, Bpp, line_bytes, server_line_bytes);
457 make_stream(s);
458 init_stream(s, MAX_BITMAP_BUF_SIZE);
459
460 if (session->client_info->use_bitmap_comp)
461 {
462 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: compression");
463 make_stream(temp_s);
464 init_stream(temp_s, 65536);
465 i = 0;
466
467 if (cy <= height)
468 {
469 i = cy;
470 }
471
472 while (i > 0)
473 {
474 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d", i);
475
476 total_bufsize = 0;
477 num_updates = 0;
478 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
479 out_uint16_le(s, RDP_UPDATE_BITMAP); /* updateType */
480 p_num_updates = s->p;
481 out_uint8s(s, 2); /* num_updates set later */
482
483 do
484 {
485 if (session->client_info->op1)
486 {
487 s_push_layer(s, channel_hdr, 18);
488 }
489 else
490 {
491 s_push_layer(s, channel_hdr, 26);
492 }
493
494 p = s->p;
495
496 if (bpp > 24)
497 {
498 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: 32 bpp");
499 lines_sending = xrdp_bitmap32_compress(data, width, height,
500 s, 32,
501 (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
502 i - 1, temp_s, e, 0x10);
503 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d",
504 i, lines_sending);
505 }
506 else
507 {
508 lines_sending = xrdp_bitmap_compress(data, width, height,
509 s, bpp,
510 (MAX_BITMAP_BUF_SIZE - 100) - total_bufsize,
511 i - 1, temp_s, e);
512 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: i %d lines_sending %d",
513 i, lines_sending);
514 }
515
516 if (lines_sending == 0)
517 {
518 break;
519 }
520
521 num_updates++;
522 bufsize = s->p - p;
523 total_bufsize += bufsize;
524 i = i - lines_sending;
525 s_mark_end(s);
526 s_pop_layer(s, channel_hdr);
527 out_uint16_le(s, x); /* left */
528 out_uint16_le(s, y + i); /* top */
529 out_uint16_le(s, (x + cx) - 1); /* right */
530 out_uint16_le(s, (y + i + lines_sending) - 1); /* bottom */
531 out_uint16_le(s, width + e); /* width */
532 out_uint16_le(s, lines_sending); /* height */
533 out_uint16_le(s, bpp); /* bpp */
534
535 if (session->client_info->op1)
536 {
537 out_uint16_le(s, 0x401); /* compress */
538 out_uint16_le(s, bufsize); /* compressed size */
539 j = (width + e) * Bpp;
540 j = j * lines_sending;
541 total_bufsize += 18; /* bytes since pop layer */
542 }
543 else
544 {
545 out_uint16_le(s, 0x1); /* compress */
546 out_uint16_le(s, bufsize + 8);
547 out_uint8s(s, 2); /* pad */
548 out_uint16_le(s, bufsize); /* compressed size */
549 j = (width + e) * Bpp;
550 out_uint16_le(s, j); /* line size */
551 j = j * lines_sending;
552 out_uint16_le(s, j); /* final size */
553 total_bufsize += 26; /* bytes since pop layer */
554 }
555
556 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: decompressed pixels %d "
557 "decompressed bytes %d compressed bytes %d",
558 lines_sending * (width + e),
559 line_pad_bytes * lines_sending, bufsize);
560
561 if (j > MAX_BITMAP_BUF_SIZE)
562 {
563 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, decompressed "
564 "size too big: %d bytes", j);
565 }
566
567 if (bufsize > MAX_BITMAP_BUF_SIZE)
568 {
569 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, compressed size "
570 "too big: %d bytes", bufsize);
571 }
572
573 s->p = s->end;
574 }
575 while (total_bufsize < MAX_BITMAP_BUF_SIZE && i > 0);
576
577 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: num_updates %d total_bufsize %d",
578 num_updates, total_bufsize);
579
580 p_num_updates[0] = num_updates;
581 p_num_updates[1] = num_updates >> 8;
582 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_BITMAP_DATA "
583 "updateType %d (UPDATETYPE_BITMAP), numberRectangles %d, "
584 "rectangles <omitted from log>",
585 RDP_UPDATE_BITMAP, num_updates);
586
587 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
588 RDP_DATA_PDU_UPDATE);
589
590 if (total_bufsize > MAX_BITMAP_BUF_SIZE)
591 {
592 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, total compressed "
593 "size too big: %d bytes", total_bufsize);
594 }
595 }
596
597 free_stream(temp_s);
598 }
599 else
600 {
601 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_bitmap: no compression");
602 total_lines = height;
603 i = 0;
604 p = data;
605
606 if (line_bytes > 0 && total_lines > 0)
607 {
608 while (i < total_lines)
609 {
610
611 lines_sending = (MAX_BITMAP_BUF_SIZE - 100) / line_pad_bytes;
612
613 if (i + lines_sending > total_lines)
614 {
615 lines_sending = total_lines - i;
616 }
617
618 if (lines_sending == 0)
619 {
620 LOG(LOG_LEVEL_WARNING, "libxrdp_send_bitmap: error, lines_sending == zero");
621 break;
622 }
623
624 p += server_line_bytes * lines_sending;
625 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
626 out_uint16_le(s, RDP_UPDATE_BITMAP);
627 out_uint16_le(s, 1); /* num updates */
628 out_uint16_le(s, x);
629 out_uint16_le(s, y + i);
630 out_uint16_le(s, (x + cx) - 1);
631 out_uint16_le(s, (y + i + lines_sending) - 1);
632 out_uint16_le(s, width + e);
633 out_uint16_le(s, lines_sending);
634 out_uint16_le(s, bpp); /* bpp */
635 out_uint16_le(s, 0); /* compress */
636 out_uint16_le(s, line_pad_bytes * lines_sending); /* bufsize */
637 q = p;
638
639 switch (bpp)
640 {
641 case 8:
642 for (j = 0; j < lines_sending; j++)
643 {
644 q = q - line_bytes;
645 out_uint8a(s, q, line_bytes);
646 out_uint8s(s, e);
647 }
648 break;
649 case 15:
650 case 16:
651 for (j = 0; j < lines_sending; j++)
652 {
653 q = q - server_line_bytes;
654 for (k = 0; k < width; k++)
655 {
656 pixel = *((tui16 *)(q + k * 2));
657 out_uint16_le(s, pixel);
658 }
659 out_uint8s(s, e * 2);
660 }
661 break;
662 case 24:
663 for (j = 0; j < lines_sending; j++)
664 {
665 q = q - server_line_bytes;
666 for (k = 0; k < width; k++)
667 {
668 pixel = *((tui32 *)(q + k * 4));
669 out_uint8(s, pixel);
670 out_uint8(s, pixel >> 8);
671 out_uint8(s, pixel >> 16);
672 }
673 out_uint8s(s, e * 3);
674 }
675 break;
676 case 32:
677 for (j = 0; j < lines_sending; j++)
678 {
679 q = q - server_line_bytes;
680 for (k = 0; k < width; k++)
681 {
682 pixel = *((int *)(q + k * 4));
683 out_uint32_le(s, pixel);
684 }
685 out_uint8s(s, e * 4);
686 }
687 break;
688 }
689
690 s_mark_end(s);
691 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_UPDATE_BITMAP_DATA "
692 "updateType %d (UPDATETYPE_BITMAP), numberRectangles 1, "
693 "rectangles <omitted from log>",
694 RDP_UPDATE_BITMAP);
695 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
696 RDP_DATA_PDU_UPDATE);
697 i = i + lines_sending;
698 }
699 }
700 }
701
702 free_stream(s);
703 return 0;
704 }
705
706 /*****************************************************************************/
707 int EXPORT_CC
libxrdp_send_pointer(struct xrdp_session * session,int cache_idx,char * data,char * mask,int x,int y,int bpp)708 libxrdp_send_pointer(struct xrdp_session *session, int cache_idx,
709 char *data, char *mask, int x, int y, int bpp)
710 {
711 struct stream *s;
712 char *p;
713 tui16 *p16;
714 tui32 *p32;
715 int i;
716 int j;
717 int data_bytes;
718
719 LOG_DEVEL(LOG_LEVEL_DEBUG, "sending cursor");
720 if (bpp == 0)
721 {
722 bpp = 24;
723 }
724 /* error check */
725 if ((session->client_info->pointer_flags & 1) == 0)
726 {
727 if (bpp != 24)
728 {
729 LOG(LOG_LEVEL_ERROR, "Send pointer: client does not support "
730 "new cursors. The only valid bpp is 24, received %d", bpp);
731 return 1;
732 }
733 }
734
735 if ((bpp != 16) && (bpp != 24) && (bpp != 32))
736 {
737 LOG(LOG_LEVEL_ERROR,
738 "Send pointer: invalid bpp value. Expected 16 or 24 or 32, "
739 "received %d", bpp);
740 return 1;
741 }
742 make_stream(s);
743 init_stream(s, 8192);
744
745 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
746 {
747 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: fastpath");
748 if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
749 {
750 LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: xrdp_rdp_init_fastpath failed");
751 free_stream(s);
752 return 1;
753 }
754
755 if ((session->client_info->pointer_flags & 1) == 0)
756 {
757 data_bytes = 3072;
758 }
759 else
760 {
761 data_bytes = ((bpp + 7) / 8) * 32 * 32;
762 out_uint16_le(s, bpp); /* TS_FP_POINTERATTRIBUTE -> newPointerUpdateData.xorBpp */
763 }
764 }
765 else /* slowpath */
766 {
767 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_send_pointer: slowpath");
768 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
769 if ((session->client_info->pointer_flags & 1) == 0)
770 {
771 out_uint16_le(s, RDP_POINTER_COLOR);
772 out_uint16_le(s, 0); /* pad */
773 data_bytes = 3072;
774 LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
775 "messageType %d (TS_PTRMSGTYPE_COLOR), pad2Octets <ignored>",
776 RDP_POINTER_COLOR);
777 }
778 else
779 {
780 out_uint16_le(s, RDP_POINTER_POINTER);
781 out_uint16_le(s, 0); /* pad */
782 LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
783 "messageType %d (TS_PTRMSGTYPE_POINTER), pad2Octets <ignored>",
784 RDP_POINTER_POINTER);
785
786 out_uint16_le(s, bpp); /* TS_POINTERATTRIBUTE -> xorBpp */
787 data_bytes = ((bpp + 7) / 8) * 32 * 32;
788 }
789 }
790
791 /* the TS_COLORPOINTERATTRIBUTE field which is shared by
792 all of the pointer attribute PDU types */
793 out_uint16_le(s, cache_idx); /* cache_idx */
794 out_uint16_le(s, x); /* hotSpot.xPos */
795 out_uint16_le(s, y); /* hotSpot.yPos */
796 out_uint16_le(s, 32); /* width */
797 out_uint16_le(s, 32); /* height */
798 out_uint16_le(s, 128); /* lengthAndMask */
799 out_uint16_le(s, data_bytes); /* lengthXorMask */
800
801 /* xorMaskData */
802 switch (bpp)
803 {
804 //case 15: /* coverity: this is logically dead code */
805 case 16:
806 p16 = (tui16 *) data;
807 for (i = 0; i < 32; i++)
808 {
809 for (j = 0; j < 32; j++)
810 {
811 out_uint16_le(s, *p16);
812 p16++;
813 }
814 }
815 break;
816 case 24:
817 p = data;
818 for (i = 0; i < 32; i++)
819 {
820 for (j = 0; j < 32; j++)
821 {
822 out_uint8(s, *p);
823 p++;
824 out_uint8(s, *p);
825 p++;
826 out_uint8(s, *p);
827 p++;
828 }
829 }
830 break;
831 case 32:
832 p32 = (tui32 *) data;
833 for (i = 0; i < 32; i++)
834 {
835 for (j = 0; j < 32; j++)
836 {
837 out_uint32_le(s, *p32);
838 p32++;
839 }
840 }
841 break;
842 }
843
844 out_uint8a(s, mask, 128); /* andMaskData */
845 out_uint8(s, 0); /* pad */
846 s_mark_end(s);
847 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
848 {
849 if ((session->client_info->pointer_flags & 1) == 0)
850 {
851 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_COLORPOINTERATTRIBUTE "
852 "cachedPointerUpdateData = { cacheIndex %d, "
853 "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
854 "height 32, lengthAndMask 128, lengthXorMask %d, "
855 "xorMaskData <omitted from log>, "
856 "andMaskData <omitted from log> }",
857 cache_idx, x, y, data_bytes);
858 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
859 FASTPATH_UPDATETYPE_COLOR) != 0)
860 {
861 LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: xrdp_rdp_send_fastpath failed");
862 free_stream(s);
863 return 1;
864 }
865 }
866 else
867 {
868 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_POINTERATTRIBUTE "
869 "newPointerUpdateData.xorBpp %d, "
870 "newPointerUpdateData.colorPtrAttr = { cacheIndex %d, "
871 "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
872 "height 32, lengthAndMask 128, lengthXorMask %d, "
873 "xorMaskData <omitted from log>, "
874 "andMaskData <omitted from log> }",
875 bpp, cache_idx, x, y, data_bytes);
876 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
877 FASTPATH_UPDATETYPE_POINTER) != 0)
878 {
879 LOG(LOG_LEVEL_ERROR, "libxrdp_send_pointer: xrdp_rdp_send_fastpath failed");
880 free_stream(s);
881 return 1;
882 }
883 }
884 }
885 else
886 {
887 if ((session->client_info->pointer_flags & 1) == 0)
888 {
889 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_COLORPOINTERATTRIBUTE "
890 "cacheIndex %d, "
891 "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
892 "height 32, lengthAndMask 128, lengthXorMask %d, "
893 "xorMaskData <omitted from log>, "
894 "andMaskData <omitted from log>",
895 cache_idx, x, y, data_bytes);
896 }
897 else
898 {
899 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_POINTERATTRIBUTE "
900 "xorBpp %d, colorPtrAttr = { cacheIndex %d, "
901 "hotSpot.xPos %d, hotSpot.yPos %d, width 32, "
902 "height 32, lengthAndMask 128, lengthXorMask %d, "
903 "xorMaskData <omitted from log>, "
904 "andMaskData <omitted from log> }",
905 bpp, cache_idx, x, y, data_bytes);
906 }
907 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
908 RDP_DATA_PDU_POINTER);
909 }
910 free_stream(s);
911 return 0;
912 }
913
914 /*****************************************************************************/
915 int EXPORT_CC
libxrdp_set_pointer(struct xrdp_session * session,int cache_idx)916 libxrdp_set_pointer(struct xrdp_session *session, int cache_idx)
917 {
918 struct stream *s;
919
920 make_stream(s);
921 init_stream(s, 8192);
922
923 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
924 {
925 if (xrdp_rdp_init_fastpath((struct xrdp_rdp *)session->rdp, s) != 0)
926 {
927 LOG(LOG_LEVEL_ERROR, "libxrdp_set_pointer: xrdp_rdp_init_fastpath failed");
928 free_stream(s);
929 return 1;
930 }
931 }
932 else
933 {
934 xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s);
935 out_uint16_le(s, RDP_POINTER_CACHED);
936 out_uint16_le(s, 0); /* pad */
937 LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_POINTER_PDU "
938 "messageType %d (TS_PTRMSGTYPE_CACHED), pad2Octets <ignored>",
939 RDP_POINTER_CACHED);
940 }
941
942 out_uint16_le(s, cache_idx); /* cache_idx */
943 s_mark_end(s);
944
945 if (session->client_info->use_fast_path & 1) /* fastpath output supported */
946 {
947 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FP_CACHEDPOINTERATTRIBUTE "
948 "cachedPointerUpdateData.cacheIndex %d", cache_idx);
949 if (xrdp_rdp_send_fastpath((struct xrdp_rdp *)session->rdp, s,
950 FASTPATH_UPDATETYPE_CACHED) != 0)
951 {
952 LOG(LOG_LEVEL_ERROR, "libxrdp_set_pointer: xrdp_rdp_send_fastpath failed");
953 free_stream(s);
954 return 1;
955 }
956 }
957 else
958 {
959 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_CACHEDPOINTERATTRIBUTE "
960 "cacheIndex %d", cache_idx);
961 xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s,
962 RDP_DATA_PDU_POINTER);
963 }
964 free_stream(s);
965 return 0;
966 }
967
968 /******************************************************************************/
969 int EXPORT_CC
libxrdp_orders_init(struct xrdp_session * session)970 libxrdp_orders_init(struct xrdp_session *session)
971 {
972 return xrdp_orders_init((struct xrdp_orders *)session->orders);
973 }
974
975 /******************************************************************************/
976 int EXPORT_CC
libxrdp_orders_send(struct xrdp_session * session)977 libxrdp_orders_send(struct xrdp_session *session)
978 {
979 return xrdp_orders_send((struct xrdp_orders *)session->orders);
980 }
981
982 /******************************************************************************/
983 int EXPORT_CC
libxrdp_orders_force_send(struct xrdp_session * session)984 libxrdp_orders_force_send(struct xrdp_session *session)
985 {
986 return xrdp_orders_force_send((struct xrdp_orders *)session->orders);
987 }
988
989 /******************************************************************************/
990 int EXPORT_CC
libxrdp_orders_rect(struct xrdp_session * session,int x,int y,int cx,int cy,int color,struct xrdp_rect * rect)991 libxrdp_orders_rect(struct xrdp_session *session, int x, int y,
992 int cx, int cy, int color, struct xrdp_rect *rect)
993 {
994 return xrdp_orders_rect((struct xrdp_orders *)session->orders,
995 x, y, cx, cy, color, rect);
996 }
997
998 /******************************************************************************/
999 int EXPORT_CC
libxrdp_orders_screen_blt(struct xrdp_session * session,int x,int y,int cx,int cy,int srcx,int srcy,int rop,struct xrdp_rect * rect)1000 libxrdp_orders_screen_blt(struct xrdp_session *session, int x, int y,
1001 int cx, int cy, int srcx, int srcy,
1002 int rop, struct xrdp_rect *rect)
1003 {
1004 return xrdp_orders_screen_blt((struct xrdp_orders *)session->orders,
1005 x, y, cx, cy, srcx, srcy, rop, rect);
1006 }
1007
1008 /******************************************************************************/
1009 int EXPORT_CC
libxrdp_orders_pat_blt(struct xrdp_session * session,int x,int y,int cx,int cy,int rop,int bg_color,int fg_color,struct xrdp_brush * brush,struct xrdp_rect * rect)1010 libxrdp_orders_pat_blt(struct xrdp_session *session, int x, int y,
1011 int cx, int cy, int rop, int bg_color,
1012 int fg_color, struct xrdp_brush *brush,
1013 struct xrdp_rect *rect)
1014 {
1015 return xrdp_orders_pat_blt((struct xrdp_orders *)session->orders,
1016 x, y, cx, cy, rop, bg_color, fg_color,
1017 brush, rect);
1018 }
1019
1020 /******************************************************************************/
1021 int EXPORT_CC
libxrdp_orders_dest_blt(struct xrdp_session * session,int x,int y,int cx,int cy,int rop,struct xrdp_rect * rect)1022 libxrdp_orders_dest_blt(struct xrdp_session *session, int x, int y,
1023 int cx, int cy, int rop,
1024 struct xrdp_rect *rect)
1025 {
1026 return xrdp_orders_dest_blt((struct xrdp_orders *)session->orders,
1027 x, y, cx, cy, rop, rect);
1028 }
1029
1030 /******************************************************************************/
1031 int EXPORT_CC
libxrdp_orders_line(struct xrdp_session * session,int mix_mode,int startx,int starty,int endx,int endy,int rop,int bg_color,struct xrdp_pen * pen,struct xrdp_rect * rect)1032 libxrdp_orders_line(struct xrdp_session *session, int mix_mode,
1033 int startx, int starty,
1034 int endx, int endy, int rop, int bg_color,
1035 struct xrdp_pen *pen,
1036 struct xrdp_rect *rect)
1037 {
1038 return xrdp_orders_line((struct xrdp_orders *)session->orders,
1039 mix_mode, startx, starty, endx, endy,
1040 rop, bg_color, pen, rect);
1041 }
1042
1043 /******************************************************************************/
1044 int EXPORT_CC
libxrdp_orders_mem_blt(struct xrdp_session * session,int cache_id,int color_table,int x,int y,int cx,int cy,int rop,int srcx,int srcy,int cache_idx,struct xrdp_rect * rect)1045 libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id,
1046 int color_table, int x, int y, int cx, int cy,
1047 int rop, int srcx, int srcy,
1048 int cache_idx, struct xrdp_rect *rect)
1049 {
1050 return xrdp_orders_mem_blt((struct xrdp_orders *)session->orders,
1051 cache_id, color_table, x, y, cx, cy, rop,
1052 srcx, srcy, cache_idx, rect);
1053 }
1054
1055 /******************************************************************************/
1056 int
libxrdp_orders_composite_blt(struct xrdp_session * session,int srcidx,int srcformat,int srcwidth,int srcrepeat,int * srctransform,int mskflags,int mskidx,int mskformat,int mskwidth,int mskrepeat,int op,int srcx,int srcy,int mskx,int msky,int dstx,int dsty,int width,int height,int dstformat,struct xrdp_rect * rect)1057 libxrdp_orders_composite_blt(struct xrdp_session *session, int srcidx,
1058 int srcformat, int srcwidth, int srcrepeat,
1059 int *srctransform, int mskflags,
1060 int mskidx, int mskformat, int mskwidth,
1061 int mskrepeat, int op, int srcx, int srcy,
1062 int mskx, int msky, int dstx, int dsty,
1063 int width, int height, int dstformat,
1064 struct xrdp_rect *rect)
1065 {
1066 return xrdp_orders_composite_blt((struct xrdp_orders *)session->orders,
1067 srcidx, srcformat, srcwidth, srcrepeat,
1068 srctransform, mskflags,
1069 mskidx, mskformat, mskwidth, mskrepeat,
1070 op, srcx, srcy, mskx, msky, dstx, dsty,
1071 width, height, dstformat, rect);
1072 }
1073
1074 /******************************************************************************/
1075 int EXPORT_CC
libxrdp_orders_text(struct xrdp_session * session,int font,int flags,int mixmode,int fg_color,int bg_color,int clip_left,int clip_top,int clip_right,int clip_bottom,int box_left,int box_top,int box_right,int box_bottom,int x,int y,char * data,int data_len,struct xrdp_rect * rect)1076 libxrdp_orders_text(struct xrdp_session *session,
1077 int font, int flags, int mixmode,
1078 int fg_color, int bg_color,
1079 int clip_left, int clip_top,
1080 int clip_right, int clip_bottom,
1081 int box_left, int box_top,
1082 int box_right, int box_bottom,
1083 int x, int y, char *data, int data_len,
1084 struct xrdp_rect *rect)
1085 {
1086 return xrdp_orders_text((struct xrdp_orders *)session->orders,
1087 font, flags, mixmode, fg_color, bg_color,
1088 clip_left, clip_top, clip_right, clip_bottom,
1089 box_left, box_top, box_right, box_bottom,
1090 x, y, data, data_len, rect);
1091 }
1092
1093 /******************************************************************************/
1094 int EXPORT_CC
libxrdp_orders_send_palette(struct xrdp_session * session,int * palette,int cache_id)1095 libxrdp_orders_send_palette(struct xrdp_session *session, int *palette,
1096 int cache_id)
1097 {
1098 return xrdp_orders_send_palette((struct xrdp_orders *)session->orders,
1099 palette, cache_id);
1100 }
1101
1102 /*****************************************************************************/
1103 int EXPORT_CC
libxrdp_orders_send_raw_bitmap(struct xrdp_session * session,int width,int height,int bpp,char * data,int cache_id,int cache_idx)1104 libxrdp_orders_send_raw_bitmap(struct xrdp_session *session,
1105 int width, int height, int bpp, char *data,
1106 int cache_id, int cache_idx)
1107 {
1108 return xrdp_orders_send_raw_bitmap((struct xrdp_orders *)session->orders,
1109 width, height, bpp, data,
1110 cache_id, cache_idx);
1111 }
1112
1113 /*****************************************************************************/
1114 int EXPORT_CC
libxrdp_orders_send_bitmap(struct xrdp_session * session,int width,int height,int bpp,char * data,int cache_id,int cache_idx)1115 libxrdp_orders_send_bitmap(struct xrdp_session *session,
1116 int width, int height, int bpp, char *data,
1117 int cache_id, int cache_idx)
1118 {
1119 return xrdp_orders_send_bitmap((struct xrdp_orders *)session->orders,
1120 width, height, bpp, data,
1121 cache_id, cache_idx);
1122 }
1123
1124 /*****************************************************************************/
1125 int EXPORT_CC
libxrdp_orders_send_font(struct xrdp_session * session,struct xrdp_font_char * font_char,int font_index,int char_index)1126 libxrdp_orders_send_font(struct xrdp_session *session,
1127 struct xrdp_font_char *font_char,
1128 int font_index, int char_index)
1129 {
1130 return xrdp_orders_send_font((struct xrdp_orders *)session->orders,
1131 font_char, font_index, char_index);
1132 }
1133
1134 /*****************************************************************************/
1135 /* Note : if this is called on a multimon setup, the client is resized
1136 * to a single monitor */
1137 int EXPORT_CC
libxrdp_reset(struct xrdp_session * session,int width,int height,int bpp)1138 libxrdp_reset(struct xrdp_session *session,
1139 int width, int height, int bpp)
1140 {
1141 if (session->client_info != 0)
1142 {
1143 struct xrdp_client_info *client_info = session->client_info;
1144
1145 /* older client can't resize */
1146 if (client_info->build <= 419)
1147 {
1148 return 0;
1149 }
1150
1151 /* if same (and only one monitor on client) don't need to do anything */
1152 if (client_info->width == width &&
1153 client_info->height == height &&
1154 client_info->bpp == bpp &&
1155 (client_info->monitorCount == 0 || client_info->multimon == 0))
1156 {
1157 return 0;
1158 }
1159
1160 client_info->width = width;
1161 client_info->height = height;
1162 client_info->bpp = bpp;
1163 client_info->monitorCount = 0;
1164 client_info->multimon = 0;
1165 }
1166 else
1167 {
1168 LOG(LOG_LEVEL_ERROR, "libxrdp_reset: session->client_info is NULL");
1169 return 1;
1170 }
1171
1172 /* this will send any lingering orders */
1173 if (xrdp_orders_reset((struct xrdp_orders *)session->orders) != 0)
1174 {
1175 LOG(LOG_LEVEL_ERROR, "libxrdp_reset: xrdp_orders_reset failed");
1176 return 1;
1177 }
1178
1179 /* shut down the rdp client
1180 *
1181 * When resetting the lib, disable application input checks, as
1182 * otherwise we can send a channel message to the other end while
1183 * the channels are inactive ([MS-RDPBCGR] 3.2.5.5.1 */
1184 session->check_for_app_input = 0;
1185 if (xrdp_rdp_send_deactivate((struct xrdp_rdp *)session->rdp) != 0)
1186 {
1187 LOG(LOG_LEVEL_ERROR, "libxrdp_reset: xrdp_rdp_send_deactivate failed");
1188 return 1;
1189 }
1190
1191 /* this should do the resizing */
1192 if (xrdp_caps_send_demand_active((struct xrdp_rdp *)session->rdp) != 0)
1193 {
1194 LOG(LOG_LEVEL_ERROR, "libxrdp_reset: xrdp_caps_send_demand_active failed");
1195 return 1;
1196 }
1197
1198 /* Re-enable application input checks */
1199 session->check_for_app_input = 1;
1200
1201 return 0;
1202 }
1203
1204 /*****************************************************************************/
1205 int EXPORT_CC
libxrdp_orders_send_raw_bitmap2(struct xrdp_session * session,int width,int height,int bpp,char * data,int cache_id,int cache_idx)1206 libxrdp_orders_send_raw_bitmap2(struct xrdp_session *session,
1207 int width, int height, int bpp, char *data,
1208 int cache_id, int cache_idx)
1209 {
1210 return xrdp_orders_send_raw_bitmap2((struct xrdp_orders *)session->orders,
1211 width, height, bpp, data,
1212 cache_id, cache_idx);
1213 }
1214
1215 /*****************************************************************************/
1216 int EXPORT_CC
libxrdp_orders_send_bitmap2(struct xrdp_session * session,int width,int height,int bpp,char * data,int cache_id,int cache_idx,int hints)1217 libxrdp_orders_send_bitmap2(struct xrdp_session *session,
1218 int width, int height, int bpp, char *data,
1219 int cache_id, int cache_idx, int hints)
1220 {
1221 return xrdp_orders_send_bitmap2((struct xrdp_orders *)session->orders,
1222 width, height, bpp, data,
1223 cache_id, cache_idx, hints);
1224 }
1225
1226 /*****************************************************************************/
1227 int EXPORT_CC
libxrdp_orders_send_bitmap3(struct xrdp_session * session,int width,int height,int bpp,char * data,int cache_id,int cache_idx,int hints)1228 libxrdp_orders_send_bitmap3(struct xrdp_session *session,
1229 int width, int height, int bpp, char *data,
1230 int cache_id, int cache_idx, int hints)
1231 {
1232 return xrdp_orders_send_bitmap3((struct xrdp_orders *)session->orders,
1233 width, height, bpp, data,
1234 cache_id, cache_idx, hints);
1235 }
1236
1237 /*****************************************************************************/
1238 int EXPORT_CC
libxrdp_get_channel_count(const struct xrdp_session * session)1239 libxrdp_get_channel_count(const struct xrdp_session *session)
1240 {
1241 int count = 0;
1242 const struct xrdp_rdp *rdp = (const struct xrdp_rdp *)session->rdp;
1243 const struct xrdp_mcs *mcs = rdp->sec_layer->mcs_layer;
1244
1245 if (mcs->channel_list == NULL)
1246 {
1247 LOG(LOG_LEVEL_WARNING,
1248 "libxrdp_get_channel_count - No channel initialized");
1249 }
1250 else
1251 {
1252 count = mcs->channel_list->count;
1253 }
1254
1255 return count;
1256 }
1257
1258 /*****************************************************************************/
1259 /* returns error */
1260 /* this function gets the channel name and its flags, index is zero
1261 based. either channel_name or channel_flags can be passed in nil if
1262 they are not needed */
1263 int EXPORT_CC
libxrdp_query_channel(struct xrdp_session * session,int channel_id,char * channel_name,int * channel_flags)1264 libxrdp_query_channel(struct xrdp_session *session, int channel_id,
1265 char *channel_name, int *channel_flags)
1266 {
1267 int count = 0;
1268 struct xrdp_rdp *rdp = (struct xrdp_rdp *)NULL;
1269 struct xrdp_mcs *mcs = (struct xrdp_mcs *)NULL;
1270 struct mcs_channel_item *channel_item = (struct mcs_channel_item *)NULL;
1271
1272 rdp = (struct xrdp_rdp *)session->rdp;
1273 mcs = rdp->sec_layer->mcs_layer;
1274
1275 if (mcs->channel_list == NULL)
1276 {
1277 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - No channel initialized");
1278 return 1 ;
1279 }
1280
1281 count = mcs->channel_list->count;
1282
1283 if (channel_id < 0 || channel_id >= count)
1284 {
1285 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel: Channel index out of range. "
1286 "max channel index %d, received channel index %d",
1287 count, channel_id);
1288 return 1;
1289 }
1290
1291 channel_item = (struct mcs_channel_item *)
1292 list_get_item(mcs->channel_list, channel_id);
1293
1294 if (channel_item == NULL)
1295 {
1296 /* this should not happen */
1297 LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel - channel item is NULL");
1298 return 1;
1299 }
1300
1301 if (channel_name != 0)
1302 {
1303 g_strncpy(channel_name, channel_item->name, 8);
1304 LOG(LOG_LEVEL_DEBUG, "libxrdp_query_channel - Channel %d name %s",
1305 channel_id, channel_name);
1306 }
1307
1308 if (channel_flags != 0)
1309 {
1310 *channel_flags = channel_item->flags;
1311 }
1312
1313 return 0;
1314 }
1315
1316 /*****************************************************************************/
1317 /* returns a zero based index of the channel, -1 if error or it doesn't
1318 exist */
1319 int EXPORT_CC
libxrdp_get_channel_id(struct xrdp_session * session,const char * name)1320 libxrdp_get_channel_id(struct xrdp_session *session, const char *name)
1321 {
1322 int index = 0;
1323 int count = 0;
1324 struct xrdp_rdp *rdp = NULL;
1325 struct xrdp_mcs *mcs = NULL;
1326 struct mcs_channel_item *channel_item = NULL;
1327
1328 rdp = (struct xrdp_rdp *)session->rdp;
1329 mcs = rdp->sec_layer->mcs_layer;
1330
1331 if (mcs->channel_list == NULL)
1332 {
1333 LOG(LOG_LEVEL_ERROR, "libxrdp_get_channel_id No channel initialized");
1334 return -1 ;
1335 }
1336
1337 count = mcs->channel_list->count;
1338
1339 for (index = 0; index < count; index++)
1340 {
1341 channel_item = (struct mcs_channel_item *)
1342 list_get_item(mcs->channel_list, index);
1343
1344 if (channel_item != 0)
1345 {
1346 if (g_strcasecmp(name, channel_item->name) == 0)
1347 {
1348 return index;
1349 }
1350 }
1351 }
1352
1353 return -1;
1354 }
1355
1356 /*****************************************************************************/
1357 int EXPORT_CC
libxrdp_send_to_channel(struct xrdp_session * session,int channel_id,char * data,int data_len,int total_data_len,int flags)1358 libxrdp_send_to_channel(struct xrdp_session *session, int channel_id,
1359 char *data, int data_len,
1360 int total_data_len, int flags)
1361 {
1362 struct xrdp_rdp *rdp = NULL;
1363 struct xrdp_sec *sec = NULL;
1364 struct xrdp_channel *chan = NULL;
1365 struct stream *s = NULL;
1366
1367 rdp = (struct xrdp_rdp *)session->rdp;
1368 sec = rdp->sec_layer;
1369 chan = sec->chan_layer;
1370 make_stream(s);
1371 init_stream(s, data_len + 1024); /* this should be big enough */
1372
1373 if (xrdp_channel_init(chan, s) != 0)
1374 {
1375 LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: xrdp_channel_init failed");
1376 free_stream(s);
1377 return 1;
1378 }
1379
1380 /* here we make a copy of the data */
1381 out_uint8a(s, data, data_len);
1382 s_mark_end(s);
1383 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] Virtual Channel PDU "
1384 "data <omitted from log>");
1385
1386 if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0)
1387 {
1388 LOG(LOG_LEVEL_ERROR, "libxrdp_send_to_channel: xrdp_channel_send failed");
1389 free_stream(s);
1390 return 1;
1391 }
1392
1393 free_stream(s);
1394 return 0;
1395 }
1396
1397 /*****************************************************************************/
1398 int
libxrdp_disable_channel(struct xrdp_session * session,int channel_id,int is_disabled)1399 libxrdp_disable_channel(struct xrdp_session *session, int channel_id,
1400 int is_disabled)
1401 {
1402 struct xrdp_rdp *rdp;
1403 struct xrdp_mcs *mcs;
1404 struct mcs_channel_item *channel_item;
1405
1406 rdp = (struct xrdp_rdp *) (session->rdp);
1407 mcs = rdp->sec_layer->mcs_layer;
1408 if (mcs->channel_list == NULL)
1409 {
1410 LOG(LOG_LEVEL_ERROR, "Channel list is NULL");
1411 return 1;
1412 }
1413 channel_item = (struct mcs_channel_item *)
1414 list_get_item(mcs->channel_list, channel_id);
1415 if (channel_item == NULL)
1416 {
1417 LOG(LOG_LEVEL_ERROR, "Channel item is NULL");
1418 return 1;
1419 }
1420 channel_item->disabled = is_disabled;
1421 LOG(LOG_LEVEL_DEBUG, "%s channel %d (%s)",
1422 (is_disabled ? "Disabling" : "Enabling"), channel_item->chanid,
1423 channel_item->name);
1424 return 1;
1425 }
1426
1427 /*****************************************************************************/
1428 int
libxrdp_drdynvc_open(struct xrdp_session * session,const char * name,int flags,struct xrdp_drdynvc_procs * procs,int * chan_id)1429 libxrdp_drdynvc_open(struct xrdp_session *session, const char *name,
1430 int flags, struct xrdp_drdynvc_procs *procs,
1431 int *chan_id)
1432 {
1433 struct xrdp_rdp *rdp;
1434 struct xrdp_sec *sec;
1435 struct xrdp_channel *chan;
1436
1437 rdp = (struct xrdp_rdp *) (session->rdp);
1438 sec = rdp->sec_layer;
1439 chan = sec->chan_layer;
1440 return xrdp_channel_drdynvc_open(chan, name, flags, procs, chan_id);
1441 }
1442
1443 /*****************************************************************************/
1444 int
libxrdp_drdynvc_close(struct xrdp_session * session,int chan_id)1445 libxrdp_drdynvc_close(struct xrdp_session *session, int chan_id)
1446 {
1447 struct xrdp_rdp *rdp;
1448 struct xrdp_sec *sec;
1449 struct xrdp_channel *chan;
1450
1451 rdp = (struct xrdp_rdp *) (session->rdp);
1452 sec = rdp->sec_layer;
1453 chan = sec->chan_layer;
1454 return xrdp_channel_drdynvc_close(chan, chan_id);
1455 }
1456
1457 /*****************************************************************************/
1458 int
libxrdp_drdynvc_data_first(struct xrdp_session * session,int chan_id,const char * data,int data_bytes,int total_data_bytes)1459 libxrdp_drdynvc_data_first(struct xrdp_session *session, int chan_id,
1460 const char *data, int data_bytes,
1461 int total_data_bytes)
1462 {
1463 struct xrdp_rdp *rdp;
1464 struct xrdp_sec *sec;
1465 struct xrdp_channel *chan;
1466
1467 rdp = (struct xrdp_rdp *) (session->rdp);
1468 sec = rdp->sec_layer;
1469 chan = sec->chan_layer;
1470 return xrdp_channel_drdynvc_data_first(chan, chan_id, data, data_bytes,
1471 total_data_bytes);
1472 }
1473
1474 /*****************************************************************************/
1475 int
libxrdp_drdynvc_data(struct xrdp_session * session,int chan_id,const char * data,int data_bytes)1476 libxrdp_drdynvc_data(struct xrdp_session *session, int chan_id,
1477 const char *data, int data_bytes)
1478 {
1479 struct xrdp_rdp *rdp;
1480 struct xrdp_sec *sec;
1481 struct xrdp_channel *chan;
1482
1483 rdp = (struct xrdp_rdp *) (session->rdp);
1484 sec = rdp->sec_layer;
1485 chan = sec->chan_layer;
1486 return xrdp_channel_drdynvc_data(chan, chan_id, data, data_bytes);
1487 }
1488
1489 /*****************************************************************************/
1490 int EXPORT_CC
libxrdp_orders_send_brush(struct xrdp_session * session,int width,int height,int bpp,int type,int size,char * data,int cache_id)1491 libxrdp_orders_send_brush(struct xrdp_session *session,
1492 int width, int height, int bpp, int type,
1493 int size, char *data, int cache_id)
1494 {
1495 return xrdp_orders_send_brush((struct xrdp_orders *)session->orders,
1496 width, height, bpp, type, size, data,
1497 cache_id);
1498 }
1499
1500 /*****************************************************************************/
1501 int EXPORT_CC
libxrdp_orders_send_create_os_surface(struct xrdp_session * session,int id,int width,int height,struct list * del_list)1502 libxrdp_orders_send_create_os_surface(struct xrdp_session *session, int id,
1503 int width, int height,
1504 struct list *del_list)
1505 {
1506 return xrdp_orders_send_create_os_surface
1507 ((struct xrdp_orders *)(session->orders), id,
1508 width, height, del_list);
1509 }
1510
1511 /*****************************************************************************/
1512 int EXPORT_CC
libxrdp_orders_send_switch_os_surface(struct xrdp_session * session,int id)1513 libxrdp_orders_send_switch_os_surface(struct xrdp_session *session, int id)
1514 {
1515 return xrdp_orders_send_switch_os_surface
1516 ((struct xrdp_orders *)(session->orders), id);
1517 }
1518
1519 /*****************************************************************************/
1520 int EXPORT_CC
libxrdp_window_new_update(struct xrdp_session * session,int window_id,struct rail_window_state_order * window_state,int flags)1521 libxrdp_window_new_update(struct xrdp_session *session, int window_id,
1522 struct rail_window_state_order *window_state,
1523 int flags)
1524 {
1525 struct xrdp_orders *orders;
1526
1527 orders = (struct xrdp_orders *)(session->orders);
1528 return xrdp_orders_send_window_new_update(orders, window_id,
1529 window_state, flags);
1530 }
1531
1532 /*****************************************************************************/
1533 int EXPORT_CC
libxrdp_window_delete(struct xrdp_session * session,int window_id)1534 libxrdp_window_delete(struct xrdp_session *session, int window_id)
1535 {
1536 struct xrdp_orders *orders;
1537
1538 orders = (struct xrdp_orders *)(session->orders);
1539 return xrdp_orders_send_window_delete(orders, window_id);
1540 }
1541
1542 /*****************************************************************************/
1543 int EXPORT_CC
libxrdp_window_icon(struct xrdp_session * session,int window_id,int cache_entry,int cache_id,struct rail_icon_info * icon_info,int flags)1544 libxrdp_window_icon(struct xrdp_session *session, int window_id,
1545 int cache_entry, int cache_id,
1546 struct rail_icon_info *icon_info, int flags)
1547 {
1548 struct xrdp_orders *orders;
1549
1550 orders = (struct xrdp_orders *)(session->orders);
1551 return xrdp_orders_send_window_icon(orders, window_id, cache_entry,
1552 cache_id, icon_info, flags);
1553 }
1554
1555 /*****************************************************************************/
1556 int EXPORT_CC
libxrdp_window_cached_icon(struct xrdp_session * session,int window_id,int cache_entry,int cache_id,int flags)1557 libxrdp_window_cached_icon(struct xrdp_session *session, int window_id,
1558 int cache_entry, int cache_id,
1559 int flags)
1560 {
1561 struct xrdp_orders *orders;
1562
1563 orders = (struct xrdp_orders *)(session->orders);
1564 return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry,
1565 cache_id, flags);
1566 }
1567
1568 /*****************************************************************************/
1569 int EXPORT_CC
libxrdp_notify_new_update(struct xrdp_session * session,int window_id,int notify_id,struct rail_notify_state_order * notify_state,int flags)1570 libxrdp_notify_new_update(struct xrdp_session *session,
1571 int window_id, int notify_id,
1572 struct rail_notify_state_order *notify_state,
1573 int flags)
1574 {
1575 struct xrdp_orders *orders;
1576
1577 orders = (struct xrdp_orders *)(session->orders);
1578 return xrdp_orders_send_notify_new_update(orders, window_id, notify_id,
1579 notify_state, flags);
1580 }
1581
1582 /*****************************************************************************/
1583 int
libxrdp_notify_delete(struct xrdp_session * session,int window_id,int notify_id)1584 libxrdp_notify_delete(struct xrdp_session *session,
1585 int window_id, int notify_id)
1586 {
1587 struct xrdp_orders *orders;
1588
1589 orders = (struct xrdp_orders *)(session->orders);
1590 return xrdp_orders_send_notify_delete(orders, window_id, notify_id);
1591 }
1592
1593 /*****************************************************************************/
1594 int
libxrdp_monitored_desktop(struct xrdp_session * session,struct rail_monitored_desktop_order * mdo,int flags)1595 libxrdp_monitored_desktop(struct xrdp_session *session,
1596 struct rail_monitored_desktop_order *mdo,
1597 int flags)
1598 {
1599 struct xrdp_orders *orders;
1600
1601 orders = (struct xrdp_orders *)(session->orders);
1602 return xrdp_orders_send_monitored_desktop(orders, mdo, flags);
1603 }
1604
1605 /*****************************************************************************/
1606 int EXPORT_CC
libxrdp_codec_jpeg_compress(struct xrdp_session * session,int format,char * inp_data,int width,int height,int stride,int x,int y,int cx,int cy,int quality,char * out_data,int * io_len)1607 libxrdp_codec_jpeg_compress(struct xrdp_session *session,
1608 int format, char *inp_data,
1609 int width, int height,
1610 int stride, int x, int y,
1611 int cx, int cy, int quality,
1612 char *out_data, int *io_len)
1613 {
1614 struct xrdp_orders *orders;
1615 void *jpeg_han;
1616
1617 orders = (struct xrdp_orders *)(session->orders);
1618 jpeg_han = orders->jpeg_han;
1619 return xrdp_codec_jpeg_compress(jpeg_han, format, inp_data,
1620 width, height, stride, x, y,
1621 cx, cy, quality, out_data, io_len);
1622 }
1623
1624 /*****************************************************************************/
1625 int EXPORT_CC
libxrdp_fastpath_send_surface(struct xrdp_session * session,char * data_pad,int pad_bytes,int data_bytes,int destLeft,int destTop,int destRight,int destBottom,int bpp,int codecID,int width,int height)1626 libxrdp_fastpath_send_surface(struct xrdp_session *session,
1627 char *data_pad, int pad_bytes,
1628 int data_bytes,
1629 int destLeft, int destTop,
1630 int destRight, int destBottom, int bpp,
1631 int codecID, int width, int height)
1632 {
1633 struct stream ls;
1634 struct stream *s;
1635 struct xrdp_rdp *rdp;
1636 int sec_bytes;
1637 int rdp_bytes;
1638 int max_bytes;
1639 int cmd_bytes;
1640
1641 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_surface:");
1642 if ((session->client_info->use_fast_path & 1) == 0)
1643 {
1644 LOG(LOG_LEVEL_ERROR, "Sending data via fastpath is disabled");
1645 return 1;
1646 }
1647 max_bytes = session->client_info->max_fastpath_frag_bytes;
1648 if (max_bytes < 32 * 1024)
1649 {
1650 max_bytes = 32 * 1024;
1651 }
1652 rdp = (struct xrdp_rdp *) (session->rdp);
1653 rdp_bytes = xrdp_rdp_get_fastpath_bytes(rdp);
1654 sec_bytes = xrdp_sec_get_fastpath_bytes(rdp->sec_layer);
1655 cmd_bytes = 10 + 12;
1656 if (data_bytes + rdp_bytes + sec_bytes + cmd_bytes > max_bytes)
1657 {
1658 LOG(LOG_LEVEL_ERROR, "Too much data to send via fastpath. "
1659 "Max fastpath bytes %d, received bytes %d",
1660 max_bytes, (data_bytes + rdp_bytes + sec_bytes + cmd_bytes));
1661 return 1;
1662 }
1663 if (sec_bytes + rdp_bytes + cmd_bytes > pad_bytes)
1664 {
1665 LOG(LOG_LEVEL_ERROR, "Too much header to send via fastpath. "
1666 "Max fastpath header bytes %d, received bytes %d",
1667 pad_bytes, (rdp_bytes + sec_bytes + cmd_bytes));
1668 return 1;
1669 }
1670 g_memset(&ls, 0, sizeof(ls));
1671 s = &ls;
1672 s->data = (data_pad + pad_bytes) - (rdp_bytes + sec_bytes + cmd_bytes);
1673 s->sec_hdr = s->data;
1674 s->rdp_hdr = s->sec_hdr + sec_bytes;
1675 s->end = data_pad + pad_bytes + data_bytes;
1676 s->p = s->data + (rdp_bytes + sec_bytes);
1677 /* TS_SURFCMD_STREAM_SURF_BITS */
1678 out_uint16_le(s, CMDTYPE_STREAM_SURFACE_BITS);
1679 out_uint16_le(s, destLeft);
1680 out_uint16_le(s, destTop);
1681 out_uint16_le(s, destRight);
1682 out_uint16_le(s, destBottom);
1683 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_SURFCMD_STREAM_SURF_BITS "
1684 "cmdType 0x%4.4x (CMDTYPE_STREAM_SURFACE_BITS), destLeft %d, "
1685 "destTop %d, destRight %d, destBottom %d, "
1686 "bitmapData <see TS_BITMAP_DATA_EX>",
1687 CMDTYPE_STREAM_SURFACE_BITS, destLeft, destTop, destRight,
1688 destBottom);
1689
1690 /* TS_BITMAP_DATA_EX */
1691 out_uint8(s, bpp);
1692 out_uint8(s, 0);
1693 out_uint8(s, 0);
1694 out_uint8(s, codecID);
1695 out_uint16_le(s, width);
1696 out_uint16_le(s, height);
1697 out_uint32_le(s, data_bytes);
1698 LOG_DEVEL(LOG_LEVEL_TRACE, "Adding field bitmapData [MS-RDPBCGR] TS_BITMAP_DATA_EX "
1699 "bpp %d, flags 0x00, reserved 0, codecID %d, width %d, "
1700 "height %d, bitmapDataLength %d, exBitmapDataHeader <not present>, "
1701 "bitmapData <omitted from log>",
1702 bpp, codecID, width, height, data_bytes);
1703
1704 /* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
1705 if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
1706 {
1707 LOG(LOG_LEVEL_ERROR,
1708 "libxrdp_fastpath_send_surface: xrdp_rdp_send_fastpath failed");
1709 return 1;
1710 }
1711 return 0;
1712 }
1713
1714 /*****************************************************************************/
1715 int EXPORT_CC
libxrdp_fastpath_send_frame_marker(struct xrdp_session * session,int frame_action,int frame_id)1716 libxrdp_fastpath_send_frame_marker(struct xrdp_session *session,
1717 int frame_action, int frame_id)
1718 {
1719 struct stream *s;
1720 struct xrdp_rdp *rdp;
1721
1722 LOG_DEVEL(LOG_LEVEL_DEBUG, "libxrdp_fastpath_send_frame_marker:");
1723 if ((session->client_info->use_fast_path & 1) == 0)
1724 {
1725 LOG(LOG_LEVEL_ERROR, "Sending data via fastpath is disabled");
1726 return 1;
1727 }
1728 if (session->client_info->use_frame_acks == 0)
1729 {
1730 LOG(LOG_LEVEL_ERROR, "Fastpath frame acks is disabled");
1731 return 1;
1732 }
1733 rdp = (struct xrdp_rdp *) (session->rdp);
1734 make_stream(s);
1735 init_stream(s, 8192);
1736 xrdp_rdp_init_fastpath(rdp, s);
1737 out_uint16_le(s, 0x0004); /* CMDTYPE_FRAME_MARKER */
1738 out_uint16_le(s, frame_action);
1739 out_uint32_le(s, frame_id);
1740 s_mark_end(s);
1741 LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [MS-RDPBCGR] TS_FRAME_MARKER "
1742 "cmdType 0x0004 (CMDTYPE_FRAME_MARKER), frameAction 0x%4.4x, "
1743 "frameId %d", frame_action, frame_id);
1744
1745 /* 4 = FASTPATH_UPDATETYPE_SURFCMDS */
1746 if (xrdp_rdp_send_fastpath(rdp, s, 4) != 0)
1747 {
1748 LOG(LOG_LEVEL_ERROR,
1749 "libxrdp_fastpath_send_frame_marker: xrdp_rdp_send_fastpath failed");
1750 free_stream(s);
1751 return 1;
1752 }
1753 free_stream(s);
1754 return 0;
1755 }
1756
1757 /*****************************************************************************/
1758 int EXPORT_CC
libxrdp_send_session_info(struct xrdp_session * session,const char * data,int data_bytes)1759 libxrdp_send_session_info(struct xrdp_session *session, const char *data,
1760 int data_bytes)
1761 {
1762 struct xrdp_rdp *rdp;
1763
1764 rdp = (struct xrdp_rdp *) (session->rdp);
1765 return xrdp_rdp_send_session_info(rdp, data, data_bytes);
1766 }
1767
1768