/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 6 by matty, Wed Jul 5 07:44:21 2000 UTC revision 9 by matty, Tue Jul 25 12:34:29 2000 UTC
# Line 21  Line 21 
21  #include "includes.h"  #include "includes.h"
22    
23  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
24  HCONN rdp_connect(char *server)  HCONN rdp_connect(char *server, int width, int height)
25  {  {
26          HCONN conn;          HCONN conn;
         RDP_ACTIVE_PDU active;  
         uint8 type;  
27    
28          if ((conn = mcs_connect(server)) == NULL)          if ((conn = mcs_connect(server)) == NULL)
29                  return NULL;                  return NULL;
# Line 34  HCONN rdp_connect(char *server) Line 32  HCONN rdp_connect(char *server)
32          mcs_recv(conn, False); /* Server's licensing certificate */          mcs_recv(conn, False); /* Server's licensing certificate */
33          rdp_send_cert(conn);          rdp_send_cert(conn);
34          mcs_recv(conn, False);          mcs_recv(conn, False);
35            mcs_recv(conn, False);
         if (!rdp_recv_pdu(conn, &type) || (type != RDP_PDU_DEMAND_ACTIVE))  
         {  
                 fprintf(stderr, "RDP error, expected Demand Active\n");  
                 mcs_disconnect(conn);  
                 return NULL;  
         }  
   
         rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE);  
         rdp_send_confirm_active(conn);  
         rdp_send_synchronize(conn);  
         rdp_send_control(conn, RDP_CTL_COOPERATE);  
         rdp_send_control(conn, RDP_CTL_REQUEST_CONTROL);  
         rdp_recv_pdu(conn, &type); // RDP_PDU_SYNCHRONIZE  
         rdp_recv_pdu(conn, &type); // RDP_CTL_COOPERATE  
         rdp_recv_pdu(conn, &type); // RDP_CTL_GRANT_CONTROL  
         rdp_send_input(conn);  
         rdp_send_fonts(conn, 1);  
         rdp_send_fonts(conn, 2);  
         rdp_recv_pdu(conn, &type); // RDP_PDU_UNKNOWN 0x28  
36    
37          return conn;          return conn;
 }  
   
 void rdp_main_loop(HCONN conn)  
 {  
         RDP_DATA_HEADER hdr;  
         RDP_UPDATE_PDU update;  
         RDP_ORDER_STATE os;  
         uint8 type;  
   
         memset(&os, 0, sizeof(os));  
   
         while (rdp_recv_pdu(conn, &type))  
         {  
                 if (type != RDP_PDU_DATA)  
                         continue;  
   
                 rdp_io_data_header(&conn->in, &hdr);  
   
                 switch (hdr.data_pdu_type)  
                 {  
                 case RDP_DATA_PDU_UPDATE:  
                         rdp_io_update_pdu(&conn->in, &update);  
                         if (update.update_type == RDP_UPDATE_ORDERS)  
                         {  
                                 fprintf(stderr, "Received orders\n");  
                                 process_orders(conn, &os);  
                         }  
                         break;  
                 }  
         }  
 }  
   
 void prs_io_coord(STREAM s, uint16 *coord, BOOL delta)  
 {  
         uint8 change;  
   
         if (delta)  
         {  
                 prs_io_uint8(s, &change);  
                 *coord += change;  
         }  
         else  
         {  
                 lsb_io_uint16(s, coord);  
         }  
 }  
   
 void process_opaque_rect(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)  
 {  
         uint8 present;  
         prs_io_uint8(&conn->in, &present);  
   
         if (present & 1)  
                 prs_io_coord(&conn->in, &os->opaque_rect.x, delta);  
   
         if (present & 2)  
                 prs_io_coord(&conn->in, &os->opaque_rect.y, delta);  
   
         if (present & 4)  
                 prs_io_coord(&conn->in, &os->opaque_rect.cx, delta);  
   
         if (present & 8)  
                 prs_io_coord(&conn->in, &os->opaque_rect.cy, delta);  
   
         if (present & 16)  
                 prs_io_uint8(&conn->in, &os->opaque_rect.colour);  
   
         fprintf(stderr, "Opaque rectangle at %d, %d\n", os->opaque_rect.x, os->opaque_rect.y);  
 }  
   
 void process_bmpcache(HCONN conn)  
 {  
   
         RDP_BITMAP_HEADER rbh;  
         char *bmpdata;  
         HBITMAP bmp;  
         static int x = 0;  
   
         rdp_io_bitmap_header(&conn->in, &rbh);  
         fprintf(stderr, "Decompressing bitmap %d x %d, final size %d\n", rbh.width, rbh.height, rbh.final_size);  
   
         bmpdata = malloc(rbh.width * rbh.height);  
         bitmap_decompress(conn->in.data  
                           + conn->in.offset, rbh.size,  
                           bmpdata, rbh.width);  
         conn->in.offset += rbh.size;  
   
         bmp = ui_create_bitmap(conn->wnd, rbh.width, rbh.height, bmpdata);  
         ui_paint_bitmap(conn->wnd, bmp, x, 0);  
         ui_destroy_bitmap(bmp);  
   
         x += rbh.width;  
 }  
   
 void process_orders(HCONN conn, RDP_ORDER_STATE *os)  
 {  
         uint16 num_orders;  
         int processed = 0;  
         BOOL res = True;  
         //      unsigned char *p;  
   
         lsb_io_uint16(&conn->in, &num_orders);  
   
         conn->in.offset += 2;  
         //      p = &conn->in.data[conn->in.offset];  
38    
         //      fprintf(stderr, "%02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);  
   
         while ((processed < num_orders) && res)  
         {  
                 uint8 order_flags;  
   
                 prs_io_uint8(&conn->in, &order_flags);  
   
                 if (!(order_flags & RDP_ORDER_STANDARD))  
                         return;  
   
                 if (order_flags & RDP_ORDER_SECONDARY)  
                 {  
                         RDP_SECONDARY_ORDER rso;  
   
                         rdp_io_secondary_order(&conn->in, &rso);  
                         switch (rso.type)  
                         {  
                         case RDP_ORDER_BMPCACHE:  
                                 process_bmpcache(conn);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Unknown secondary order %d\n",  
                                         rso.type);  
                                 return;  
                         }  
   
   
                 }  
   
                 if (order_flags & RDP_ORDER_CHANGE)  
                         prs_io_uint8(&conn->in, &os->order_type);  
   
                 switch (os->order_type)  
                 {  
                 case RDP_ORDER_OPAQUE_RECT:  
                         process_opaque_rect(conn, os, order_flags & RDP_ORDER_DELTA);  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown order %d\n", os->order_type);  
                         return;  
                 }  
   
                 processed++;  
         }  
39  }  }
40    
41  /* Work this out later. This is useless anyway when encryption is off. */  /* Work this out later. This is useless anyway when encryption is off. */
# Line 218  uint8 precanned_key_packet[] = { Line 47  uint8 precanned_key_packet[] = {
47     0xd8,0xe5,0x00,0x00,0x00,0x00,0x00,0x00     0xd8,0xe5,0x00,0x00,0x00,0x00,0x00,0x00
48  };  };
49    
50    uint8 precanned_key_packet_e1[] = {
51    0x01,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x7c,0xbd,0x8b,0x8f,0x16,0x2b,0xa1,0x00,
52    0xc6,0xfb,0x8a,0x39,0xf5,0x33,0xed,0x36,0x14,0x55,0x17,0x8c,0x3a,0xde,0x5e,0xdf,
53    0xcb,0x41,0x4c,0xc7,0x89,0x7d,0xe3,0xe9,0x34,0x08,0xda,0xdc,0x08,0x77,0x98,0xda,
54    0x65,0xae,0x27,0x74,0xf1,0x79,0xd0,0x28,0x54,0x64,0x86,0x7f,0x02,0xe0,0x71,0x51,
55    0x56,0x4e,0xca,0x72,0x94,0x62,0x49,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
56    };
57    
58    uint8 precanned_key_packet_e2[] = {
59    0x48,0x00,0x00,0x00,0x8a,0xe4,0x9f,0x8a,0xd5,0x04,0x02,0xfd,0x09,0x1f,0xff,0x53,
60    0xe0,0xb2,0x72,0x8b,0x19,0xba,0x22,0xe4,0x2a,0x7b,0xeb,0x79,0xa8,0x83,0x31,0x6f,
61    0x5c,0xcc,0x37,0x9c,0xe8,0x73,0x64,0x64,0xd3,0xab,0xaa,0x9f,0xbe,0x49,0x27,0xfc,
62    0x95,0xf3,0x6e,0xf8,0xb1,0x01,0x7c,0xba,0xa9,0xc5,0x35,0x9c,0x8f,0x74,0x3a,0x9f,
63    0xd4,0x26,0x4d,0x39,0x90,0xbe,0xf4,0xfb,0x72,0x9e,0x54,0x18
64    };
65    
66  /* Create an RC4 key and transfer it to the server */  /* Create an RC4 key and transfer it to the server */
67  void rdp_establish_key(HCONN conn)  void rdp_establish_key(HCONN conn)
68  {  {
# Line 229  void rdp_establish_key(HCONN conn) Line 74  void rdp_establish_key(HCONN conn)
74          mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);          mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);
75  }  }
76    
77    /* Create an RC4 key and transfer it to the server */
78    void rdp_establish_key_e1(HCONN conn)
79    {
80            mcs_init_data(conn);
81            memcpy(conn->out.data + conn->out.offset, precanned_key_packet_e1,
82                   sizeof(precanned_key_packet_e1));
83            conn->out.offset += sizeof(precanned_key_packet_e1);
84            MARK_END(conn->out);
85            mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);
86    }
87    
88    /* Create an RC4 key and transfer it to the server */
89    void rdp_establish_key_e2(HCONN conn)
90    {
91            mcs_init_data(conn);
92            memcpy(conn->out.data + conn->out.offset, precanned_key_packet_e2,
93                   sizeof(precanned_key_packet_e2));
94            conn->out.offset += sizeof(precanned_key_packet_e2);
95            MARK_END(conn->out);
96            mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);
97    }
98    
99  /* Horrible horrible certificate stuff. Work out later. */  /* Horrible horrible certificate stuff. Work out later. */
100  uint8 precanned_cert_packet[] = {  uint8 precanned_cert_packet[] = { // 4c8
101  0x80,0x00,0x00,0x00,0x12,0x02,0xb4,0x04,0x01,0x00,0x00,  0x80,0x00,0x00,0x00,0x12,0x02,0xb4,0x04,0x01,0x00,0x00,
102  0x00,0x00,0x00,0x01,0x02,0x9d,0xa3,0x7a,0x93,0x34,0x7b,0x28,0x37,0x24,0xa0,0x1f,  0x00,0x00,0x00,0x01,0x02,0x9d,0xa3,0x7a,0x93,0x34,0x7b,0x28,0x37,0x24,0xa0,0x1f,
103  0x61,0x26,0xfd,0x96,0x3a,0x92,0x83,0xf3,0xe9,0x6a,0x2e,0x81,0x7c,0x2c,0xe4,0x72,//  0x61,0x26,0xfd,0x96,0x3a,0x92,0x83,0xf3,0xe9,0x6a,0x2e,0x81,0x7c,0x2c,0xe4,0x72,//
# Line 361  void rdp_send_data(HCONN conn, uint16 da Line 228  void rdp_send_data(HCONN conn, uint16 da
228          mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);          mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);
229  }  }
230    
231  void rdp_send_confirm_active(HCONN conn)  void rdp_send_confirm_active(HCONN conn, uint32 shareid, int width, int height)
232  {  {
233          RDP_ACTIVE_PDU active;          RDP_ACTIVE_PDU active;
234    
235          rdp_init(conn);          rdp_init(conn);
236          rdp_make_active_pdu(&active, 0x103ea, conn->mcs_userid);          rdp_make_active_pdu(&active, shareid, conn->mcs_userid, width, height);
237          rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);          rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);
238          MARK_END(conn->out);          MARK_END(conn->out);
239          rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);          rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);
# Line 374  void rdp_send_confirm_active(HCONN conn) Line 241  void rdp_send_confirm_active(HCONN conn)
241    
242  void rdp_send_synchronize(HCONN conn)  void rdp_send_synchronize(HCONN conn)
243  {  {
244          RDP_SYNCHRONIZE_PDU sync;          RDP_SYNCHRONISE_PDU sync;
245    
246          rdp_init_data(conn);          rdp_init_data(conn);
247          rdp_make_synchronize_pdu(&sync, 1002);          rdp_make_synchronise_pdu(&sync, 1002);
248          rdp_io_synchronize_pdu(&conn->out, &sync);          rdp_io_synchronise_pdu(&conn->out, &sync);
249          MARK_END(conn->out);          MARK_END(conn->out);
250          rdp_send_data(conn, RDP_DATA_PDU_SYNCHRONIZE);          rdp_send_data(conn, RDP_DATA_PDU_SYNCHRONIZE);
251  }  }
# Line 405  void rdp_send_fonts(HCONN conn, uint16 s Line 272  void rdp_send_fonts(HCONN conn, uint16 s
272          rdp_send_data(conn, RDP_DATA_PDU_FONT2);          rdp_send_data(conn, RDP_DATA_PDU_FONT2);
273  }  }
274    
275  void rdp_send_input(HCONN conn)  void rdp_send_input(HCONN conn, uint16 message_type, uint16 device_flags,
276                                    uint16 param1, uint16 param2)
277  {  {
278          RDP_INPUT_PDU input;          RDP_INPUT_PDU input;
279    
280          rdp_init_data(conn);          rdp_init_data(conn);
281          rdp_make_input_pdu(&input);          rdp_make_input_pdu(&input, message_type, device_flags, param1, param2);
282          rdp_io_input_pdu(&conn->out, &input);          rdp_io_input_pdu(&conn->out, &input);
283          MARK_END(conn->out);          MARK_END(conn->out);
284          rdp_send_data(conn, RDP_DATA_PDU_INPUT);          rdp_send_data(conn, RDP_DATA_PDU_INPUT);
# Line 420  BOOL rdp_recv_pdu(HCONN conn, uint8 *typ Line 288  BOOL rdp_recv_pdu(HCONN conn, uint8 *typ
288  {  {
289          RDP_HEADER hdr;          RDP_HEADER hdr;
290    
291          if (!mcs_recv(conn, False) || !rdp_io_header(&conn->in, &hdr))          conn->in.offset = conn->in.rdp_offset;
292    
293            if (conn->in.offset >= conn->in.end)
294            {
295                    if (!mcs_recv(conn, False))
296                            return False;
297            }
298    
299            if (!rdp_io_header(&conn->in, &hdr))
300                  return False;                  return False;
301    
302            conn->in.rdp_offset += hdr.length;
303          *type = hdr.pdu_type & 0xf;          *type = hdr.pdu_type & 0xf;
304    
305    #if DUMP
306            fprintf(stderr, "RDP packet (type %x):\n", *type);
307            dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);
308    #endif
309    
310          return True;          return True;
311  }  }
312    
# Line 433  void rdp_disconnect(HCONN conn) Line 316  void rdp_disconnect(HCONN conn)
316          mcs_disconnect(conn);          mcs_disconnect(conn);
317  }  }
318    
319    /* Construct an RDP header */
320  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,
321                       uint16 userid)                       uint16 userid)
322  {  {
# Line 441  void rdp_make_header(RDP_HEADER *hdr, ui Line 325  void rdp_make_header(RDP_HEADER *hdr, ui
325          hdr->userid = userid + 1001;          hdr->userid = userid + 1001;
326  }  }
327    
328    /* Parse an RDP header */
329    BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)
330    {
331            BOOL res = True;
332    
333            res = res ? lsb_io_uint16(s, &hdr->length  ) : False;
334            res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;
335            if ((hdr->pdu_type & 0xf) != RDP_PDU_DEACTIVATE)
336                    res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;
337    
338            return res;
339    }
340    
341    /* Construct a data header */
342  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,
343                            uint16 length, uint16 data_pdu_type)                            uint16 length, uint16 data_pdu_type)
344  {  {
# Line 453  void rdp_make_data_header(RDP_DATA_HEADE Line 351  void rdp_make_data_header(RDP_DATA_HEADE
351          hdr->compress_len = 0;          hdr->compress_len = 0;
352  }  }
353    
354  void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)  /* Parse a data header */
355    BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)
356  {  {
357          caps->os_major_type = 1;          BOOL res = True;
         caps->os_minor_type = 3;  
         caps->ver_protocol = 0x200;  
 }  
358    
359  void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps)          res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;
360  {          res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;
361          caps->preferred_bpp = 8;          res = res ? prs_io_uint8 (s, &hdr->streamid     ) : False;
362          caps->receive1bpp = 1;          res = res ? lsb_io_uint16(s, &hdr->length       ) : False;
363          caps->receive4bpp = 1;          res = res ? prs_io_uint8 (s, &hdr->data_pdu_type) : False;
364          caps->receive8bpp = 1;          res = res ? prs_io_uint8 (s, &hdr->compress_type) : False;
365          caps->width = 640;          res = res ? lsb_io_uint16(s, &hdr->compress_len ) : False;
366          caps->height = 480;  
367          caps->compression = 1;          return res;
         caps->unknown2 = 1;  
368  }  }
369    
370  void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  BOOL rdp_io_present(STREAM s, uint32 *present, uint8 flags, int size)
371  {  {
372          caps->xgranularity = 1;          uint8 bits;
373          caps->ygranularity = 20;          int i;
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
374    
375  //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;          if (flags & RDP_ORDER_SMALL)
376            {
377                    size--;
378            }
379    
380          caps->support[0] = caps->support[1] = caps->support[2]          if (flags & RDP_ORDER_TINY)
381                  = caps->support[3] = caps->support[4] = caps->support[5]          {
382                  = caps->support[6] = caps->support[8] = caps->support[11]                  if (size < 2)
383                  = caps->support[12] = caps->support[22] = caps->support[28]                          return False;
384                  = caps->support[29] = caps->support[30] = 1;  
385          caps->text_cap_flags = 0x6A1;                  size -= 2;
386          caps->desk_save_size = 0x38400;          }
387          caps->unknown2 = 0x4E4;  
388            *present = 0;
389            for (i = 0; i < size; i++)
390            {
391                    prs_io_uint8(s, &bits);
392                    *present |= bits << (i * 8);
393            }
394    
395            return True;
396  }  }
397    
398  void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)  BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)
399  {  {
400          caps->caches[0].entries = 0x258;          uint8 change;
401          caps->caches[0].max_cell_size = 0x100;          BOOL res;
402          caps->caches[1].entries = 0x12c;  
403          caps->caches[1].max_cell_size = 0x400;          if (delta)
404          caps->caches[2].entries = 0x106;          {
405          caps->caches[2].max_cell_size = 0x1000;                  res = prs_io_uint8(s, &change);
406                    *coord += (char)change;
407            }
408            else
409            {
410                    res = lsb_io_uint16(s, coord);
411            }
412    
413            return res;
414  }  }
415    
416  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)  BOOL rdp_io_colour(STREAM s, uint8 *colour)
417  {  {
418          caps->control_interest = 2;          BOOL res;
419          caps->detach_interest = 2;  
420            res = prs_io_uint8(s, colour);
421            s->offset += 2;
422    
423            return res;
424  }  }
425    
426  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)  BOOL rdp_io_colourmap(STREAM s, COLOURMAP *colours)
427  {  {
428            int datasize;
429    
430            lsb_io_uint16(s, &colours->ncolours);
431            datasize = colours->ncolours * 3;
432    
433            if (datasize > sizeof(colours->colours))
434                    return False;
435    
436            memcpy(colours->colours, s->data + s->offset, datasize);
437            s->offset += datasize;
438            return True;
439  }  }
440    
441  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)  BOOL rdp_io_bounds(STREAM s, BOUNDS *bounds)
442  {  {
443          caps->colour_pointer = 0;          uint8 present;
444          caps->cache_size = 20;  
445            prs_io_uint8(s, &present);
446    
447            if (present & 1)
448                    rdp_io_coord(s, &bounds->left, False);
449            else if (present & 16)
450                    rdp_io_coord(s, &bounds->left, True);
451    
452            if (present & 2)
453                    rdp_io_coord(s, &bounds->top, False);
454            else if (present & 32)
455                    rdp_io_coord(s, &bounds->top, True);
456    
457            if (present & 4)
458                    rdp_io_coord(s, &bounds->right, False);
459            else if (present & 64)
460                    rdp_io_coord(s, &bounds->right, True);
461    
462            if (present & 8)
463                    rdp_io_coord(s, &bounds->bottom, False);
464            else if (present & 128)
465                    rdp_io_coord(s, &bounds->bottom, True);
466    
467            return True;
468  }  }
469    
470  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)  BOOL rdp_io_pen(STREAM s, PEN *pen, uint32 present)
471  {  {
472            BOOL res = True;
473    
474            if (present & 1)
475                    res = res ? prs_io_uint8(s, &pen->style) : False;
476    
477            if (present & 2)
478                    res = res ? prs_io_uint8(s, &pen->width) : False;
479    
480            if (present & 4)
481                    res = res ? rdp_io_colour(s, &pen->colour) : False;
482    
483            return res;
484  }  }
485    
486  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)  BOOL rdp_io_brush(STREAM s, BRUSH *brush, uint32 present)
487  {  {
488          caps->cache_size = 6;          BOOL res = True;
489    
490            if (present & 1)
491                    res = res ? prs_io_uint8(s, &brush->xorigin) : False;
492    
493            if (present & 2)
494                    res = res ? prs_io_uint8(s, &brush->yorigin) : False;
495    
496            if (present & 4)
497                    res = res ? prs_io_uint8(s, &brush->style) : False;
498    
499            if (present & 8)
500                    res = res ? prs_io_uint8(s, &brush->pattern[0]) : False;
501    
502            if (present & 16)
503                    res = res ? prs_io_uint8s(s, &brush->pattern[1], 7) : False;
504    
505            return res;
506  }  }
507    
508  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid)  /* Construct a confirm/demand active PDU */
509    void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid,
510                                    int width, int height)
511  {  {
512          memset(pdu, 0, sizeof(*pdu));          memset(pdu, 0, sizeof(*pdu));
513          pdu->shareid = shareid;          pdu->shareid = shareid;
# Line 542  void rdp_make_active_pdu(RDP_ACTIVE_PDU Line 522  void rdp_make_active_pdu(RDP_ACTIVE_PDU
522          pdu->num_caps = 0xD;          pdu->num_caps = 0xD;
523    
524          rdp_make_general_caps (&pdu->general_caps );          rdp_make_general_caps (&pdu->general_caps );
525          rdp_make_bitmap_caps  (&pdu->bitmap_caps  );          rdp_make_bitmap_caps  (&pdu->bitmap_caps, width, height);
526          rdp_make_order_caps   (&pdu->order_caps   );          rdp_make_order_caps   (&pdu->order_caps   );
527          rdp_make_bmpcache_caps(&pdu->bmpcache_caps);          rdp_make_bmpcache_caps(&pdu->bmpcache_caps);
528          rdp_make_control_caps (&pdu->control_caps );          rdp_make_control_caps (&pdu->control_caps );
# Line 552  void rdp_make_active_pdu(RDP_ACTIVE_PDU Line 532  void rdp_make_active_pdu(RDP_ACTIVE_PDU
532          rdp_make_colcache_caps(&pdu->colcache_caps);          rdp_make_colcache_caps(&pdu->colcache_caps);
533  }  }
534    
535    /* Parse a confirm/demand active PDU */
536    BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)
537    {
538            uint16 capset;
539            uint16 length;
540            BOOL res;
541            int i;
542    
543            res = lsb_io_uint32(s, &pdu->shareid);
544    
545            if (pdutype == RDP_PDU_CONFIRM_ACTIVE)
546                    res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;
547    
548            res = res ? lsb_io_uint16(s, &pdu->source_len) : False;
549            res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;
550    
551            if (pdu->source_len > 48)
552            {
553                    ERROR("RDP source descriptor too long\n");
554                    return False;
555            }
556    
557            res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;
558            res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;
559            res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;
560    
561            if (s->marshall)
562            {
563                    capset = RDP_CAPSET_GENERAL;
564                    res = res ? lsb_io_uint16(s, &capset) : False;
565                    res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;
566    
567                    capset = RDP_CAPSET_BITMAP;
568                    res = res ? lsb_io_uint16(s, &capset) : False;
569                    res = res ? rdp_io_bitmap_caps (s, &pdu->bitmap_caps ) : False;
570    
571                    capset = RDP_CAPSET_ORDER;
572                    res = res ? lsb_io_uint16(s, &capset) : False;
573                    res = res ? rdp_io_order_caps  (s, &pdu->order_caps  ) : False;
574    
575                    capset = RDP_CAPSET_BMPCACHE;
576                    res = res ? lsb_io_uint16(s, &capset) : False;
577                    res = res ? rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps) : False;
578    
579                    capset = RDP_CAPSET_COLCACHE;
580                    res = res ? lsb_io_uint16(s, &capset) : False;
581                    res = res ? rdp_io_colcache_caps(s, &pdu->colcache_caps) : False;
582    
583                    capset = RDP_CAPSET_ACTIVATE;
584                    res = res ? lsb_io_uint16(s, &capset) : False;
585                    res = res ? rdp_io_activate_caps(s, &pdu->activate_caps) : False;
586    
587                    capset = RDP_CAPSET_CONTROL;
588                    res = res ? lsb_io_uint16(s, &capset) : False;
589                    res = res ? rdp_io_control_caps(s, &pdu->control_caps) : False;
590    
591                    capset = RDP_CAPSET_POINTER;
592                    res = res ? lsb_io_uint16(s, &capset) : False;
593                    res = res ? rdp_io_pointer_caps(s, &pdu->pointer_caps) : False;
594    
595                    capset = RDP_CAPSET_SHARE;
596                    res = res ? lsb_io_uint16(s, &capset) : False;
597                    res = res ? rdp_io_share_caps  (s, &pdu->share_caps  ) : False;
598    
599                    capset = RDP_CAPSET_UNKNOWN;
600                    res = res ? lsb_io_uint16(s, &capset) : False;
601                    res = res ? rdp_io_unknown_caps(s, NULL) : False;
602            }
603            else
604            {
605                    for (i = 0; i < pdu->num_caps; i++)
606                    {
607                            if (!res)
608                                    return False;
609    
610                            if (!lsb_io_uint16(s, &capset))
611                                    return False;
612    
613                            switch (capset)
614                            {
615                            case RDP_CAPSET_GENERAL:
616                                    res = rdp_io_general_caps (s, &pdu->general_caps );
617                                    break;
618                            case RDP_CAPSET_BITMAP:
619                                    res = rdp_io_bitmap_caps  (s, &pdu->bitmap_caps  );
620                                    break;
621                            case RDP_CAPSET_ORDER:
622                                    res = rdp_io_order_caps   (s, &pdu->order_caps   );
623                                    break;
624                            case RDP_CAPSET_BMPCACHE:
625                                    res = rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps);
626                                    break;
627                            case RDP_CAPSET_CONTROL:
628                                    res = rdp_io_control_caps (s, &pdu->control_caps );
629                                    break;
630                            case RDP_CAPSET_ACTIVATE:
631                                    res = rdp_io_activate_caps(s, &pdu->activate_caps);
632                                    break;
633                            case RDP_CAPSET_POINTER:
634                                    res = rdp_io_pointer_caps (s, &pdu->pointer_caps );
635                                    break;
636                            case RDP_CAPSET_SHARE:
637                                    res = rdp_io_share_caps   (s, &pdu->share_caps   );
638                                    break;
639                            case RDP_CAPSET_COLCACHE:
640                                    res = rdp_io_colcache_caps(s, &pdu->colcache_caps);
641                                    break;
642                            default:
643                                    NOTIMP("capset 0x%x\n", capset);
644    
645                                    if (!lsb_io_uint16(s, &length))
646                                            return False;
647    
648                                    s->offset += (length - 4);
649                            }
650                    }
651            }
652    
653            return res;
654    }
655    
656    /* Construct a control PDU */
657  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)
658  {  {
659          pdu->action = action;          pdu->action = action;
# Line 559  void rdp_make_control_pdu(RDP_CONTROL_PD Line 661  void rdp_make_control_pdu(RDP_CONTROL_PD
661          pdu->controlid = 0;          pdu->controlid = 0;
662  }  }
663    
664  void rdp_make_synchronize_pdu(RDP_SYNCHRONIZE_PDU *pdu, uint16 userid)  /* Parse a control PDU */
665    BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)
666    {
667            BOOL res = True;
668    
669            res = res ? lsb_io_uint16(s, &pdu->action   ) : False;
670            res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;
671            res = res ? lsb_io_uint32(s, &pdu->controlid) : False;
672    
673            return res;
674    }
675    
676    /* Construct a synchronisation PDU */
677    void rdp_make_synchronise_pdu(RDP_SYNCHRONISE_PDU *pdu, uint16 userid)
678  {  {
679          pdu->type = 1;          pdu->type = 1;
680          pdu->userid = userid;          pdu->userid = userid;
681  }  }
682    
683    /* Parse a synchronisation PDU */
684    BOOL rdp_io_synchronise_pdu(STREAM s, RDP_SYNCHRONISE_PDU *pdu)
685    {
686            BOOL res = True;
687    
688            res = res ? lsb_io_uint16(s, &pdu->type  ) : False;
689            res = res ? lsb_io_uint16(s, &pdu->userid) : False;
690    
691            return res;
692    }
693    
694    /* Parse a single input event */
695    BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)
696    {
697            BOOL res = True;
698    
699            res = res ? lsb_io_uint32(s, &evt->event_time)   : False;
700            res = res ? lsb_io_uint16(s, &evt->message_type) : False;
701            res = res ? lsb_io_uint16(s, &evt->device_flags) : False;
702    
703            if (!res)
704                    return False;
705    
706            switch (evt->message_type)
707            {
708            case RDP_INPUT_CODEPOINT:
709            case RDP_INPUT_VIRTKEY:
710                    res = res ? lsb_io_uint16(s, &evt->param1) : False;
711                    break;
712            case RDP_INPUT_SYNCHRONIZE:
713            case RDP_INPUT_SCANCODE:
714            case RDP_INPUT_MOUSE:
715                    res = res ? lsb_io_uint16(s, &evt->param1) : False;
716                    res = res ? lsb_io_uint16(s, &evt->param2) : False;
717                    break;
718            default:
719                    NOTIMP("input type %d\n", evt->message_type);
720                    return False;
721            }
722    
723            return res;
724    }
725    
726    /* Construct an input PDU */
727    void rdp_make_input_pdu(RDP_INPUT_PDU *pdu, uint16 message_type,
728                            uint16 device_flags, uint16 param1, uint16 param2)
729    {
730            uint32 now = time(NULL);
731    
732            pdu->num_events = 1;
733            pdu->pad = 0;
734    
735            pdu->event[0].event_time = now;
736            pdu->event[0].message_type = message_type;
737            pdu->event[0].device_flags = device_flags;
738            pdu->event[0].param1 = param1;
739            pdu->event[0].param2 = param2;
740    }
741    
742    /* Parse an input PDU */
743    BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)
744    {
745            BOOL res = True;
746            int i;
747    
748            res = res ? lsb_io_uint16(s, &pdu->num_events) : False;
749            res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;
750    
751            if (pdu->num_events > RDP_MAX_EVENTS)
752            {
753                    ERROR("Too many events in one PDU\n");
754                    return False;
755            }
756    
757            for (i = 0; i < pdu->num_events; i++)
758            {
759                    res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;
760            }
761    
762            return res;
763    }
764    
765    /* Construct a font information PDU */
766  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)
767  {  {
768          pdu->num_fonts = 0;          pdu->num_fonts = 0;
# Line 573  void rdp_make_font_pdu(RDP_FONT_PDU *pdu Line 771  void rdp_make_font_pdu(RDP_FONT_PDU *pdu
771          pdu->entry_size = RDP_FONT_INFO_SIZE;          pdu->entry_size = RDP_FONT_INFO_SIZE;
772  }  }
773    
774  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu)  /* Parse a font information structure */
775    BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)
776  {  {
777          uint32 now = time(NULL);          BOOL res = True;
778    
779          pdu->num_events = 3;          res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;
780          pdu->pad = 0;          res = res ? lsb_io_uint16(s, &font->flags    ) : False;
781            res = res ? lsb_io_uint16(s, &font->width    ) : False;
782            res = res ? lsb_io_uint16(s, &font->height   ) : False;
783            res = res ? lsb_io_uint16(s, &font->xaspect  ) : False;
784            res = res ? lsb_io_uint16(s, &font->yaspect  ) : False;
785            res = res ? lsb_io_uint32(s, &font->signature) : False;
786            res = res ? lsb_io_uint16(s, &font->codepage ) : False;
787            res = res ? lsb_io_uint16(s, &font->ascent   ) : False;
788    
789          pdu->event[0].event_time = now;          return res;
         pdu->event[0].message_type = RDP_INPUT_SYNCHRONIZE;  
         pdu->event[0].device_flags = 0;  
         pdu->event[0].mouse_x = 0;  
         pdu->event[0].mouse_y = 0;  
   
         pdu->event[1].event_time = now;  
         pdu->event[1].message_type = RDP_INPUT_UNKNOWN;  
         pdu->event[1].device_flags = 0x8000;  
         pdu->event[1].mouse_x = 15;  
         pdu->event[1].mouse_y = 0;  
   
         pdu->event[2].event_time = now;  
         pdu->event[2].message_type = RDP_INPUT_MOUSE;  
         pdu->event[2].device_flags = MOUSE_FLAG_MOVE;  
         pdu->event[2].mouse_x = 425;  
         pdu->event[2].mouse_y = 493;  
790  }  }
791    
792  BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  /* Parse a font information PDU */
793    BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)
794  {  {
795          BOOL res = True;          BOOL res = True;
796            int i;
797    
798          res = res ? lsb_io_uint16(s, &hdr->length  ) : False;          res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;
799          res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;          res = res ? lsb_io_uint16(s, &pdu->unknown1  ) : False;
800          res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;          res = res ? lsb_io_uint16(s, &pdu->unknown2  ) : False;
801            res = res ? lsb_io_uint16(s, &pdu->entry_size) : False;
802    
803            if (pdu->num_fonts > RDP_MAX_FONTS)
804            {
805                    ERROR("Too many fonts in one PDU\n");
806                    return False;
807            }
808    
809            for (i = 0; i < pdu->num_fonts; i++)
810            {
811                    res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;
812            }
813    
814          return res;          return res;
815  }  }
816    
817  BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  /* Parse a pointer PDU */
818    BOOL rdp_io_pointer_pdu(STREAM s, RDP_POINTER_PDU *ptr)
819  {  {
820          BOOL res = True;          BOOL res = True;
821    
822          res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;          res = res ? lsb_io_uint16(s, &ptr->message) : False;
823          res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;          res = res ? lsb_io_uint16(s, &ptr->pad    ) : False;
824          res = res ? prs_io_uint8 (s, &hdr->streamid     ) : False;  
825          res = res ? lsb_io_uint16(s, &hdr->length       ) : False;          switch (ptr->message)
826          res = res ? prs_io_uint8 (s, &hdr->data_pdu_type) : False;          {
827          res = res ? prs_io_uint8 (s, &hdr->compress_type) : False;                  case RDP_POINTER_MOVE:
828          res = res ? lsb_io_uint16(s, &hdr->compress_len ) : False;                          res = res ? lsb_io_uint16(s, &ptr->x      ) : False;
829                            res = res ? lsb_io_uint16(s, &ptr->y      ) : False;
830                            break;
831            }
832    
833            return res;
834    }
835    
836    /* Parse an update PDU */
837    BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)
838    {
839            BOOL res = True;
840    
841            res = res ? lsb_io_uint16(s, &pdu->update_type) : False;
842            res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;
843    
844            return res;
845    }
846    
847    
848    /* PRIMARY ORDERS */
849    
850    /* Parse an destination blt order */
851    BOOL rdp_io_destblt_order(STREAM s, DESTBLT_ORDER *os, uint32 present, BOOL delta)
852    {
853            if (present & 0x01)
854                    rdp_io_coord(s, &os->x, delta);
855    
856            if (present & 0x02)
857                    rdp_io_coord(s, &os->y, delta);
858    
859            if (present & 0x04)
860                    rdp_io_coord(s, &os->cx, delta);
861    
862            if (present & 0x08)
863                    rdp_io_coord(s, &os->cy, delta);
864    
865            if (present & 0x10)
866                    prs_io_uint8(s, &os->opcode);
867    
868            return PRS_ERROR(s);
869    }
870    
871    /* Parse an pattern blt order */
872    BOOL rdp_io_patblt_order(STREAM s, PATBLT_ORDER *os, uint32 present, BOOL delta)
873    {
874            if (present & 0x0001)
875                    rdp_io_coord(s, &os->x, delta);
876    
877            if (present & 0x0002)
878                    rdp_io_coord(s, &os->y, delta);
879    
880            if (present & 0x0004)
881                    rdp_io_coord(s, &os->cx, delta);
882    
883            if (present & 0x0008)
884                    rdp_io_coord(s, &os->cy, delta);
885    
886            if (present & 0x0010)
887                    prs_io_uint8(s, &os->opcode);
888    
889            if (present & 0x0020)
890                    rdp_io_colour(s, &os->bgcolour);
891    
892            if (present & 0x0040)
893                    rdp_io_colour(s, &os->fgcolour);
894    
895            rdp_io_brush(s, &os->brush, present >> 7);
896    
897            return PRS_ERROR(s);
898    }
899    
900    /* Parse an screen blt order */
901    BOOL rdp_io_screenblt_order(STREAM s, SCREENBLT_ORDER *os, uint32 present, BOOL delta)
902    {
903            if (present & 0x0001)
904                    rdp_io_coord(s, &os->x, delta);
905    
906            if (present & 0x0002)
907                    rdp_io_coord(s, &os->y, delta);
908    
909            if (present & 0x0004)
910                    rdp_io_coord(s, &os->cx, delta);
911    
912            if (present & 0x0008)
913                    rdp_io_coord(s, &os->cy, delta);
914    
915            if (present & 0x0010)
916                    prs_io_uint8(s, &os->opcode);
917    
918            if (present & 0x0020)
919                    rdp_io_coord(s, &os->srcx, delta);
920    
921            if (present & 0x0040)
922                    rdp_io_coord(s, &os->srcy, delta);
923    
924            return PRS_ERROR(s);
925    }
926    
927    /* Parse a line order */
928    BOOL rdp_io_line_order(STREAM s, LINE_ORDER *os, uint32 present, BOOL delta)
929    {
930            if (present & 0x0001)
931                    lsb_io_uint16(s, &os->mixmode);
932    
933            if (present & 0x0002)
934                    rdp_io_coord(s, &os->startx, delta);
935    
936            if (present & 0x0004)
937                    rdp_io_coord(s, &os->starty, delta);
938    
939            if (present & 0x0008)
940                    rdp_io_coord(s, &os->endx, delta);
941    
942            if (present & 0x0010)
943                    rdp_io_coord(s, &os->endy, delta);
944    
945            if (present & 0x0020)
946                    rdp_io_colour(s, &os->bgcolour);
947    
948            if (present & 0x0040)
949                    prs_io_uint8(s, &os->opcode);
950    
951            rdp_io_pen(s, &os->pen, present >> 7);
952    
953            return PRS_ERROR(s);
954    }
955    
956    /* Parse an opaque rectangle order */
957    BOOL rdp_io_rect_order(STREAM s, RECT_ORDER *os, uint32 present, BOOL delta)
958    {
959            if (present & 0x01)
960                    rdp_io_coord(s, &os->x, delta);
961    
962            if (present & 0x02)
963                    rdp_io_coord(s, &os->y, delta);
964    
965            if (present & 0x04)
966                    rdp_io_coord(s, &os->cx, delta);
967    
968            if (present & 0x08)
969                    rdp_io_coord(s, &os->cy, delta);
970    
971            if (present & 0x10)
972                    prs_io_uint8(s, &os->colour);
973    
974            return PRS_ERROR(s);
975    }
976    
977    /* Parse a desktop save order */
978    BOOL rdp_io_desksave_order(STREAM s, DESKSAVE_ORDER *os, uint32 present, BOOL delta)
979    {
980            if (present & 0x01)
981                    lsb_io_uint32(s, &os->offset);
982    
983            if (present & 0x02)
984                    rdp_io_coord(s, &os->left, delta);
985    
986            if (present & 0x04)
987                    rdp_io_coord(s, &os->top, delta);
988    
989            if (present & 0x08)
990                    rdp_io_coord(s, &os->right, delta);
991    
992            if (present & 0x10)
993                    rdp_io_coord(s, &os->bottom, delta);
994    
995            if (present & 0x20)
996                    prs_io_uint8(s, &os->action);
997    
998            return PRS_ERROR(s);
999    }
1000    
1001    /* Parse a memory blt order */
1002    BOOL rdp_io_memblt_order(STREAM s, MEMBLT_ORDER *os, uint32 present, BOOL delta)
1003    {
1004            if (present & 0x0001)
1005            {
1006                    prs_io_uint8(s, &os->cache_id);
1007                    prs_io_uint8(s, &os->colour_table);
1008            }
1009    
1010            if (present & 0x0002)
1011                    rdp_io_coord(s, &os->x, delta);
1012    
1013            if (present & 0x0004)
1014                    rdp_io_coord(s, &os->y, delta);
1015    
1016            if (present & 0x0008)
1017                    rdp_io_coord(s, &os->cx, delta);
1018    
1019            if (present & 0x0010)
1020                    rdp_io_coord(s, &os->cy, delta);
1021    
1022            if (present & 0x0020)
1023                    prs_io_uint8(s, &os->opcode);
1024    
1025            if (present & 0x0040)
1026                    rdp_io_coord(s, &os->srcx, delta);
1027    
1028            if (present & 0x0080)
1029                    rdp_io_coord(s, &os->srcy, delta);
1030    
1031            if (present & 0x0100)
1032                    lsb_io_uint16(s, &os->cache_idx);
1033    
1034            return PRS_ERROR(s);
1035    }
1036    
1037    /* Parse a 3-way blt order */
1038    BOOL rdp_io_triblt_order(STREAM s, TRIBLT_ORDER *os, uint32 present, BOOL delta)
1039    {
1040            if (present & 0x000001)
1041            {
1042                    prs_io_uint8(s, &os->cache_id);
1043                    prs_io_uint8(s, &os->colour_table);
1044            }
1045    
1046            if (present & 0x000002)
1047                    rdp_io_coord(s, &os->x, delta);
1048    
1049            if (present & 0x000004)
1050                    rdp_io_coord(s, &os->y, delta);
1051    
1052            if (present & 0x000008)
1053                    rdp_io_coord(s, &os->cx, delta);
1054    
1055            if (present & 0x000010)
1056                    rdp_io_coord(s, &os->cy, delta);
1057    
1058            if (present & 0x000020)
1059                    prs_io_uint8(s, &os->opcode);
1060    
1061            if (present & 0x000040)
1062                    rdp_io_coord(s, &os->srcx, delta);
1063    
1064            if (present & 0x000080)
1065                    rdp_io_coord(s, &os->srcy, delta);
1066    
1067            if (present & 0x000100)
1068                    rdp_io_colour(s, &os->bgcolour);
1069    
1070            if (present & 0x000200)
1071                    rdp_io_colour(s, &os->fgcolour);
1072    
1073            rdp_io_brush(s, &os->brush, present >> 10);
1074    
1075            if (present & 0x008000)
1076                    lsb_io_uint16(s, &os->cache_idx);
1077    
1078            if (present & 0x010000)
1079                    lsb_io_uint16(s, &os->unknown);
1080    
1081            return PRS_ERROR(s);
1082    }
1083    
1084    /* Parse a text order */
1085    BOOL rdp_io_text2_order(STREAM s, TEXT2_ORDER *os, uint32 present, BOOL delta)
1086    {
1087            if (present & 0x000001)
1088                    prs_io_uint8(s, &os->font);
1089    
1090            if (present & 0x000002)
1091                    prs_io_uint8(s, &os->flags);
1092    
1093            if (present & 0x000004)
1094                    prs_io_uint8(s, &os->unknown);
1095    
1096            if (present & 0x000008)
1097                    prs_io_uint8(s, &os->mixmode);
1098    
1099            if (present & 0x000010)
1100                    rdp_io_colour(s, &os->fgcolour);
1101    
1102            if (present & 0x000020)
1103                    rdp_io_colour(s, &os->bgcolour);
1104    
1105            if (present & 0x000040)
1106                    lsb_io_uint16(s, &os->clipleft);
1107    
1108            if (present & 0x000080)
1109                    lsb_io_uint16(s, &os->cliptop);
1110    
1111            if (present & 0x000100)
1112                    lsb_io_uint16(s, &os->clipright);
1113    
1114            if (present & 0x000200)
1115                    lsb_io_uint16(s, &os->clipbottom);
1116    
1117            if (present & 0x000400)
1118                    lsb_io_uint16(s, &os->boxleft);
1119    
1120            if (present & 0x000800)
1121                    lsb_io_uint16(s, &os->boxtop);
1122    
1123            if (present & 0x001000)
1124                    lsb_io_uint16(s, &os->boxright);
1125    
1126            if (present & 0x002000)
1127                    lsb_io_uint16(s, &os->boxbottom);
1128    
1129            if (present & 0x080000)
1130                    lsb_io_uint16(s, &os->x);
1131    
1132            if (present & 0x100000)
1133                    lsb_io_uint16(s, &os->y);
1134    
1135            if (present & 0x200000)
1136            {
1137                    prs_io_uint8(s, &os->length);
1138                    prs_io_uint8s(s, os->text, os->length);
1139            }
1140    
1141            return PRS_ERROR(s);
1142    }
1143    
1144    
1145    /* SECONDARY ORDERS */
1146    
1147    BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)
1148    {
1149            BOOL res = True;
1150    
1151            res = res ? lsb_io_uint16(s, &rso->length) : False;
1152            res = res ? lsb_io_uint16(s, &rso->flags ) : False;
1153            res = res ? prs_io_uint8 (s, &rso->type  ) : False;
1154    
1155            return res;
1156    }
1157    
1158    BOOL rdp_io_raw_bmpcache_order(STREAM s, RDP_RAW_BMPCACHE_ORDER *rbo)
1159    {
1160            BOOL res = True;
1161    
1162            res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;
1163            res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;
1164            res = res ? prs_io_uint8 (s, &rbo->width     ) : False;
1165            res = res ? prs_io_uint8 (s, &rbo->height    ) : False;
1166            res = res ? prs_io_uint8 (s, &rbo->bpp       ) : False;
1167            res = res ? lsb_io_uint16(s, &rbo->bufsize   ) : False;
1168            res = res ? lsb_io_uint16(s, &rbo->cache_idx ) : False;
1169    
1170            rbo->data = s->data + s->offset;
1171            s->offset += rbo->bufsize;
1172    
1173          return res;          return res;
1174  }  }
1175    
1176    BOOL rdp_io_bmpcache_order(STREAM s, RDP_BMPCACHE_ORDER *rbo)
1177    {
1178            BOOL res = True;
1179    
1180            res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;
1181            res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;
1182            res = res ? prs_io_uint8 (s, &rbo->width     ) : False;
1183            res = res ? prs_io_uint8 (s, &rbo->height    ) : False;
1184            res = res ? prs_io_uint8 (s, &rbo->bpp       ) : False;
1185            res = res ? lsb_io_uint16(s, &rbo->bufsize   ) : False;
1186            res = res ? lsb_io_uint16(s, &rbo->cache_idx ) : False;
1187            res = res ? lsb_io_uint16(s, &rbo->pad2      ) : False;
1188            res = res ? lsb_io_uint16(s, &rbo->size      ) : False;
1189            res = res ? lsb_io_uint16(s, &rbo->row_size  ) : False;
1190            res = res ? lsb_io_uint16(s, &rbo->final_size) : False;
1191    
1192            rbo->data = s->data + s->offset;
1193            s->offset += rbo->size;
1194    
1195            return res;
1196    }
1197    
1198    BOOL rdp_io_colcache_order(STREAM s, RDP_COLCACHE_ORDER *colours)
1199    {
1200            COLOURENTRY *entry;
1201            int i;
1202    
1203            prs_io_uint8(s, &colours->cache_id);
1204            lsb_io_uint16(s, &colours->map.ncolours);
1205    
1206            for (i = 0; i < colours->map.ncolours; i++)
1207            {
1208                    entry = &colours->map.colours[i];
1209                    prs_io_uint8(s, &entry->blue);
1210                    prs_io_uint8(s, &entry->green);
1211                    prs_io_uint8(s, &entry->red);
1212                    s->offset++;
1213            }
1214    
1215            return True;
1216    }
1217    
1218    BOOL rdp_io_fontcache_order(STREAM s, RDP_FONTCACHE_ORDER *font)
1219    {
1220            RDP_FONT_GLYPH *glyph;
1221            BOOL res = True;
1222            int i, j, datasize;
1223            uint8 in, out;
1224    
1225            res = res ? prs_io_uint8(s, &font->font   ) : False;
1226            res = res ? prs_io_uint8(s, &font->nglyphs) : False;
1227    
1228            for (i = 0; i < font->nglyphs; i++)
1229            {
1230                    glyph = &font->glyphs[i];
1231                    res = res ? lsb_io_uint16(s, &glyph->character) : False;
1232                    res = res ? lsb_io_uint16(s, &glyph->unknown  ) : False;
1233                    res = res ? lsb_io_uint16(s, &glyph->baseline ) : False;
1234                    res = res ? lsb_io_uint16(s, &glyph->width    ) : False;
1235                    res = res ? lsb_io_uint16(s, &glyph->height   ) : False;
1236    
1237                    datasize = (glyph->height * ((glyph->width + 7) / 8) + 3) & ~3;
1238                    res = res ? prs_io_uint8s(s, glyph->data, datasize) : False;
1239                    for (j = 0; j < datasize; j++)
1240                    {
1241                            in = glyph->data[j];
1242                            out = 0;
1243                            if (in & 1) out |= 128;
1244                            if (in & 2) out |= 64;
1245                            if (in & 4) out |= 32;
1246                            if (in & 8) out |= 16;
1247                            if (in & 16) out |= 8;
1248                            if (in & 32) out |= 4;
1249                            if (in & 64) out |= 2;
1250                            if (in & 128) out |= 1;
1251                            glyph->data[j] = out;
1252                    }
1253            }
1254    
1255            return res;
1256    }
1257    
1258    
1259    /* CAPABILITIES */
1260    
1261    /* Construct a general capability set */
1262    void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)
1263    {
1264            caps->os_major_type = 1;
1265            caps->os_minor_type = 3;
1266            caps->ver_protocol = 0x200;
1267    }
1268    
1269    /* Parse general capability set */
1270  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)
1271  {  {
1272          uint16 length = RDP_CAPLEN_GENERAL;          uint16 length = RDP_CAPLEN_GENERAL;
# Line 634  BOOL rdp_io_general_caps(STREAM s, RDP_G Line 1276  BOOL rdp_io_general_caps(STREAM s, RDP_G
1276          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1277          if (pkt_length != length)          if (pkt_length != length)
1278          {          {
1279                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1280                  return False;                  return False;
1281          }          }
1282    
# Line 652  BOOL rdp_io_general_caps(STREAM s, RDP_G Line 1294  BOOL rdp_io_general_caps(STREAM s, RDP_G
1294          return res;          return res;
1295  }  }
1296    
1297    /* Construct a bitmap capability set */
1298    void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps, int width, int height)
1299    {
1300            caps->preferred_bpp = 8;
1301            caps->receive1bpp = 1;
1302            caps->receive4bpp = 1;
1303            caps->receive8bpp = 1;
1304            caps->width = width;
1305            caps->height = height;
1306            caps->compression = 1;
1307            caps->unknown2 = 1;
1308    }
1309    
1310    /* Parse bitmap capability set */
1311  BOOL rdp_io_bitmap_caps(STREAM s, RDP_BITMAP_CAPS *caps)  BOOL rdp_io_bitmap_caps(STREAM s, RDP_BITMAP_CAPS *caps)
1312  {  {
1313          uint16 length = RDP_CAPLEN_BITMAP;          uint16 length = RDP_CAPLEN_BITMAP;
# Line 661  BOOL rdp_io_bitmap_caps(STREAM s, RDP_BI Line 1317  BOOL rdp_io_bitmap_caps(STREAM s, RDP_BI
1317          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1318          if (pkt_length != length)          if (pkt_length != length)
1319          {          {
1320                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1321                  return False;                  return False;
1322          }          }
1323    
# Line 681  BOOL rdp_io_bitmap_caps(STREAM s, RDP_BI Line 1337  BOOL rdp_io_bitmap_caps(STREAM s, RDP_BI
1337          return res;          return res;
1338  }  }
1339    
1340    /* Construct an order capability set */
1341    void rdp_make_order_caps(RDP_ORDER_CAPS *caps)
1342    {
1343            caps->xgranularity = 1;
1344            caps->ygranularity = 20;
1345            caps->max_order_level = 1;
1346            caps->num_fonts = 0x147;
1347            caps->cap_flags = 0x2A;
1348    
1349    //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;
1350    
1351            caps->support[0] = caps->support[1] = caps->support[2]
1352                    = caps->support[3] = caps->support[4] = caps->support[5]
1353                    = caps->support[6] = caps->support[8] = caps->support[11]
1354                    = caps->support[12] = caps->support[22] = caps->support[28]
1355                    = caps->support[29] = caps->support[30] = 1;
1356            caps->text_cap_flags = 0x6A1;
1357            caps->desk_save_size = 0x38400;
1358            caps->unknown2 = 0x4E4;
1359    }
1360    
1361    /* Parse order capability set */
1362  BOOL rdp_io_order_caps(STREAM s, RDP_ORDER_CAPS *caps)  BOOL rdp_io_order_caps(STREAM s, RDP_ORDER_CAPS *caps)
1363  {  {
1364          uint16 length = RDP_CAPLEN_ORDER;          uint16 length = RDP_CAPLEN_ORDER;
# Line 690  BOOL rdp_io_order_caps(STREAM s, RDP_ORD Line 1368  BOOL rdp_io_order_caps(STREAM s, RDP_ORD
1368          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1369          if (pkt_length != length)          if (pkt_length != length)
1370          {          {
1371                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1372                  return False;                  return False;
1373          }          }
1374    
# Line 713  BOOL rdp_io_order_caps(STREAM s, RDP_ORD Line 1391  BOOL rdp_io_order_caps(STREAM s, RDP_ORD
1391          return res;          return res;
1392  }  }
1393    
1394    /* Construct a bitmap cache capability set */
1395    void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)
1396    {
1397            caps->caches[0].entries = 0x258;
1398            caps->caches[0].max_cell_size = 0x100;
1399            caps->caches[1].entries = 0x12c;
1400            caps->caches[1].max_cell_size = 0x400;
1401            caps->caches[2].entries = 0x106;
1402            caps->caches[2].max_cell_size = 0x1000;
1403    }
1404    
1405    /* Parse single bitmap cache information structure */
1406  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)
1407  {  {
1408          if (!lsb_io_uint16(s, &info->entries      ))          if (!lsb_io_uint16(s, &info->entries      ))
# Line 724  BOOL rdp_io_bmpcache_info(STREAM s, RDP_ Line 1414  BOOL rdp_io_bmpcache_info(STREAM s, RDP_
1414          return True;          return True;
1415  }  }
1416    
1417    /* Parse bitmap cache capability set */
1418  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)
1419  {  {
1420          uint16 length = RDP_CAPLEN_BMPCACHE;          uint16 length = RDP_CAPLEN_BMPCACHE;
# Line 734  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_ Line 1425  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_
1425          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1426          if (pkt_length != length)          if (pkt_length != length)
1427          {          {
1428                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1429                  return False;                  return False;
1430          }          }
1431    
# Line 747  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_ Line 1438  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_
1438          return res;          return res;
1439  }  }
1440    
1441    /* Construct a control capability set */
1442    void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)
1443    {
1444            caps->control_interest = 2;
1445            caps->detach_interest = 2;
1446    }
1447    
1448    /* Parse control capability set */
1449  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)
1450  {  {
1451          uint16 length = RDP_CAPLEN_CONTROL;          uint16 length = RDP_CAPLEN_CONTROL;
# Line 756  BOOL rdp_io_control_caps(STREAM s, RDP_C Line 1455  BOOL rdp_io_control_caps(STREAM s, RDP_C
1455          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1456          if (pkt_length != length)          if (pkt_length != length)
1457          {          {
1458                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1459                  return False;                  return False;
1460          }          }
1461    
# Line 768  BOOL rdp_io_control_caps(STREAM s, RDP_C Line 1467  BOOL rdp_io_control_caps(STREAM s, RDP_C
1467          return res;          return res;
1468  }  }
1469    
1470    /* Construct an activation capability set */
1471    void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)
1472    {
1473    }
1474    
1475    /* Parse activation capability set */
1476  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)
1477  {  {
1478          uint16 length = RDP_CAPLEN_ACTIVATE;          uint16 length = RDP_CAPLEN_ACTIVATE;
# Line 777  BOOL rdp_io_activate_caps(STREAM s, RDP_ Line 1482  BOOL rdp_io_activate_caps(STREAM s, RDP_
1482          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1483          if (pkt_length != length)          if (pkt_length != length)
1484          {          {
1485                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1486                  return False;                  return False;
1487          }          }
1488    
# Line 789  BOOL rdp_io_activate_caps(STREAM s, RDP_ Line 1494  BOOL rdp_io_activate_caps(STREAM s, RDP_
1494          return res;          return res;
1495  }  }
1496    
1497    /* Construct a pointer capability set */
1498    void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)
1499    {
1500            caps->colour_pointer = 0;
1501            caps->cache_size = 20;
1502    }
1503    
1504    /* Parse pointer capability set */
1505  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)
1506  {  {
1507          uint16 length = RDP_CAPLEN_POINTER;          uint16 length = RDP_CAPLEN_POINTER;
# Line 798  BOOL rdp_io_pointer_caps(STREAM s, RDP_P Line 1511  BOOL rdp_io_pointer_caps(STREAM s, RDP_P
1511          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1512          if (pkt_length != length)          if (pkt_length != length)
1513          {          {
1514                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1515                  return False;                  return False;
1516          }          }
1517    
# Line 808  BOOL rdp_io_pointer_caps(STREAM s, RDP_P Line 1521  BOOL rdp_io_pointer_caps(STREAM s, RDP_P
1521          return res;          return res;
1522  }  }
1523    
1524    /* Construct a share capability set */
1525    void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)
1526    {
1527    }
1528    
1529    /* Parse share capability set */
1530  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)
1531  {  {
1532          uint16 length = RDP_CAPLEN_SHARE;          uint16 length = RDP_CAPLEN_SHARE;
# Line 817  BOOL rdp_io_share_caps(STREAM s, RDP_SHA Line 1536  BOOL rdp_io_share_caps(STREAM s, RDP_SHA
1536          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1537          if (pkt_length != length)          if (pkt_length != length)
1538          {          {
1539                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1540                  return False;                  return False;
1541          }          }
1542    
# Line 827  BOOL rdp_io_share_caps(STREAM s, RDP_SHA Line 1546  BOOL rdp_io_share_caps(STREAM s, RDP_SHA
1546          return res;          return res;
1547  }  }
1548    
1549    /* Construct a colour cache capability set */
1550    void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)
1551    {
1552            caps->cache_size = 6;
1553    }
1554    
1555    /* Parse colour cache capability set */
1556  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)
1557  {  {
1558          uint16 length = RDP_CAPLEN_COLCACHE;          uint16 length = RDP_CAPLEN_COLCACHE;
# Line 836  BOOL rdp_io_colcache_caps(STREAM s, RDP_ Line 1562  BOOL rdp_io_colcache_caps(STREAM s, RDP_
1562          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1563          if (pkt_length != length)          if (pkt_length != length)
1564          {          {
1565                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1566                  return False;                  return False;
1567          }          }
1568    
# Line 859  uint8 canned_caps[] = { Line 1585  uint8 canned_caps[] = {
1585  0x00,0x00,0x01,0x40,0x00,0x00,0x08,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00  0x00,0x00,0x01,0x40,0x00,0x00,0x08,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00
1586  };  };
1587    
1588    /* Insert canned capabilities */
1589  BOOL rdp_io_unknown_caps(STREAM s, void *caps)  BOOL rdp_io_unknown_caps(STREAM s, void *caps)
1590  {  {
1591          uint16 length = 0x58;          uint16 length = 0x58;
# Line 868  BOOL rdp_io_unknown_caps(STREAM s, void Line 1595  BOOL rdp_io_unknown_caps(STREAM s, void
1595          res = lsb_io_uint16(s, &pkt_length);          res = lsb_io_uint16(s, &pkt_length);
1596          if (pkt_length != length)          if (pkt_length != length)
1597          {          {
1598                  fprintf(stderr, "Unrecognised capabilities size\n");                  ERROR("Unrecognised capabilities size\n");
1599                  return False;                  return False;
1600          }          }
1601    
# Line 876  BOOL rdp_io_unknown_caps(STREAM s, void Line 1603  BOOL rdp_io_unknown_caps(STREAM s, void
1603    
1604          return res;          return res;
1605  }  }
   
 BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  
 {  
         uint16 capset;  
         uint16 length;  
         BOOL res;  
         int i;  
   
         res = lsb_io_uint32(s, &pdu->shareid);  
   
         if (pdutype == RDP_PDU_CONFIRM_ACTIVE)  
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
   
         res = res ? lsb_io_uint16(s, &pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
   
         if (pdu->source_len > 48)  
         {  
                 fprintf(stderr, "RDP source descriptor too long\n");  
                 return False;  
         }  
   
         res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (s->marshall)  
         {  
                 capset = RDP_CAPSET_GENERAL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;  
   
                 capset = RDP_CAPSET_BITMAP;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bitmap_caps (s, &pdu->bitmap_caps ) : False;  
   
                 capset = RDP_CAPSET_ORDER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_order_caps  (s, &pdu->order_caps  ) : False;  
   
                 capset = RDP_CAPSET_BMPCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps) : False;  
   
                 capset = RDP_CAPSET_COLCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_colcache_caps(s, &pdu->colcache_caps) : False;  
   
                 capset = RDP_CAPSET_ACTIVATE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_activate_caps(s, &pdu->activate_caps) : False;  
   
                 capset = RDP_CAPSET_CONTROL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_control_caps(s, &pdu->control_caps) : False;  
   
                 capset = RDP_CAPSET_POINTER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_pointer_caps(s, &pdu->pointer_caps) : False;  
   
                 capset = RDP_CAPSET_SHARE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_share_caps  (s, &pdu->share_caps  ) : False;  
   
                 capset = RDP_CAPSET_UNKNOWN;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_unknown_caps(s, NULL) : False;  
         }  
         else  
         {  
                 for (i = 0; i < pdu->num_caps; i++)  
                 {  
                         if (!res)  
                                 return False;  
   
                         if (!lsb_io_uint16(s, &capset))  
                                 return False;  
   
                         switch (capset)  
                         {  
                         case RDP_CAPSET_GENERAL:  
                                 res = rdp_io_general_caps (s, &pdu->general_caps );  
                                 break;  
                         case RDP_CAPSET_BITMAP:  
                                 res = rdp_io_bitmap_caps  (s, &pdu->bitmap_caps  );  
                                 break;  
                         case RDP_CAPSET_ORDER:  
                                 res = rdp_io_order_caps   (s, &pdu->order_caps   );  
                                 break;  
                         case RDP_CAPSET_BMPCACHE:  
                                 res = rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps);  
                                 break;  
                         case RDP_CAPSET_CONTROL:  
                                 res = rdp_io_control_caps (s, &pdu->control_caps );  
                                 break;  
                         case RDP_CAPSET_ACTIVATE:  
                                 res = rdp_io_activate_caps(s, &pdu->activate_caps);  
                                 break;  
                         case RDP_CAPSET_POINTER:  
                                 res = rdp_io_pointer_caps (s, &pdu->pointer_caps );  
                                 break;  
                         case RDP_CAPSET_SHARE:  
                                 res = rdp_io_share_caps   (s, &pdu->share_caps   );  
                                 break;  
                         case RDP_CAPSET_COLCACHE:  
                                 res = rdp_io_colcache_caps(s, &pdu->colcache_caps);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Warning: Unrecognised capset %x\n",  
                                         capset);  
   
                                 if (!lsb_io_uint16(s, &length))  
                                         return False;  
   
                                 s->offset += (length - 4);  
                         }  
                 }  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->action   ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;  
         res = res ? lsb_io_uint32(s, &pdu->controlid) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_synchronize_pdu(STREAM s, RDP_SYNCHRONIZE_PDU *pdu)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->type  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint32(s, &evt->event_time)   : False;  
         res = res ? lsb_io_uint16(s, &evt->message_type) : False;  
   
         if (!res)  
                 return False;  
   
         switch (evt->message_type)  
         {  
         case RDP_INPUT_CODEPOINT:  
         case RDP_INPUT_VIRTKEY:  
                 res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
                 res = res ? lsb_io_uint16(s, &evt->kbd_keycode ) : False;  
                 break;  
         case RDP_INPUT_SYNCHRONIZE:  
         case RDP_INPUT_UNKNOWN:  
         case RDP_INPUT_MOUSE:  
                 res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
                 res = res ? lsb_io_uint16(s, &evt->mouse_x     ) : False;  
                 res = res ? lsb_io_uint16(s, &evt->mouse_y     ) : False;  
                 break;  
         default:  
                 fprintf(stderr, "Unknown input type %d\n", evt->message_type);  
                 return False;  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  
 {  
         BOOL res = True;  
         int i;  
   
         res = res ? lsb_io_uint16(s, &pdu->num_events) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (pdu->num_events > RDP_MAX_EVENTS)  
         {  
                 fprintf(stderr, "Too many events in one PDU\n");  
                 return False;  
         }  
   
         for (i = 0; i < pdu->num_events; i++)  
         {  
                 res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)  
 {  
         BOOL res = True;  
   
         res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;  
         res = res ? lsb_io_uint16(s, &font->flags    ) : False;  
         res = res ? lsb_io_uint16(s, &font->width    ) : False;  
         res = res ? lsb_io_uint16(s, &font->height   ) : False;  
         res = res ? lsb_io_uint16(s, &font->xaspect  ) : False;  
         res = res ? lsb_io_uint16(s, &font->yaspect  ) : False;  
         res = res ? lsb_io_uint32(s, &font->signature) : False;  
         res = res ? lsb_io_uint16(s, &font->codepage ) : False;  
         res = res ? lsb_io_uint16(s, &font->ascent   ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  
 {  
         BOOL res = True;  
         int i;  
   
         res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->unknown1  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->unknown2  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->entry_size) : False;  
   
         if (pdu->num_fonts > RDP_MAX_FONTS)  
         {  
                 fprintf(stderr, "Too many fonts in one PDU\n");  
                 return False;  
         }  
   
         for (i = 0; i < pdu->num_fonts; i++)  
         {  
                 res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;  
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->update_type) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &rso->length) : False;  
         res = res ? lsb_io_uint16(s, &rso->flags ) : False;  
         res = res ? prs_io_uint8 (s, &rso->type  ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_bitmap_header(STREAM s, RDP_BITMAP_HEADER *rdh)  
 {  
         BOOL res = True;  
   
         res = res ? prs_io_uint8 (s, &rdh->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->cache_idx ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->pad2      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->size      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->row_size  ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->final_size) : False;  
   
         return res;  
 }  

Legend:
Removed from v.6  
changed lines
  Added in v.9

  ViewVC Help
Powered by ViewVC 1.1.26