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