Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

rdp.cpp

Go to the documentation of this file.
00001 /*
00002    rdesktop: A Remote Desktop Protocol client.
00003    Protocol services - RDP layer
00004    Copyright (C) Matthew Chapman 1999-2002
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019 */
00020 
00021 #include "rdesktop.h"
00022 
00023 extern uint16 mcs_userid;
00024 extern char username[16];
00025 extern BOOL bitmap_compression;
00026 extern BOOL orders;
00027 extern BOOL encryption;
00028 extern BOOL desktop_save;
00029 
00030 uint8 *next_packet;
00031 uint32 rdp_shareid;
00032 
00033 /* Initialise an RDP packet */
00034 static STREAM
00035 rdp_init(int maxlen)
00036 {
00037         STREAM s;
00038 
00039         s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
00040         s_push_layer(s, rdp_hdr, 6);
00041 
00042         return s;
00043 }
00044 
00045 /* Send an RDP packet */
00046 static void
00047 rdp_send(STREAM s, uint8 pdu_type)
00048 {
00049         uint16 length;
00050 
00051         s_pop_layer(s, rdp_hdr);
00052         length = s->end - s->p;
00053 
00054         out_uint16_le(s, length);
00055         out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */
00056         out_uint16_le(s, (mcs_userid + 1001));
00057 
00058         sec_send(s, encryption ? SEC_ENCRYPT : 0);
00059 }
00060 
00061 /* Receive an RDP packet */
00062 STREAM
00063 rdp_recv(uint8 * type)
00064 {
00065         static STREAM rdp_s;
00066         uint16 length, pdu_type;
00067 
00068         if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
00069         {
00070                 rdp_s = sec_recv();
00071                 if (rdp_s == NULL)
00072                         return NULL;
00073 
00074                 next_packet = rdp_s->p;
00075         }
00076         else
00077         {
00078                 rdp_s->p = next_packet;
00079         }
00080 
00081         in_uint16_le(rdp_s, length);
00082         /* 32k packets are really 8, keepalive fix */
00083         if (length == 0x8000)
00084         {
00085                 next_packet += 8;
00086                 *type = 0;
00087                 return rdp_s;
00088         }
00089         in_uint16_le(rdp_s, pdu_type);
00090         in_uint8s(rdp_s, 2);    /* userid */
00091         *type = pdu_type & 0xf;
00092 
00093 #if WITH_DEBUG
00094         DEBUG(("RDP packet (type %x):\n", *type));
00095         hexdump(next_packet, length);
00096 #endif /*  */
00097 
00098         next_packet += length;
00099         return rdp_s;
00100 }
00101 
00102 /* Initialise an RDP data packet */
00103 static STREAM
00104 rdp_init_data(int maxlen)
00105 {
00106         STREAM s;
00107 
00108         s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
00109         s_push_layer(s, rdp_hdr, 18);
00110 
00111         return s;
00112 }
00113 
00114 /* Send an RDP data packet */
00115 static void
00116 rdp_send_data(STREAM s, uint8 data_pdu_type)
00117 {
00118         uint16 length;
00119 
00120         s_pop_layer(s, rdp_hdr);
00121         length = s->end - s->p;
00122 
00123         out_uint16_le(s, length);
00124         out_uint16_le(s, (RDP_PDU_DATA | 0x10));
00125         out_uint16_le(s, (mcs_userid + 1001));
00126 
00127         out_uint32_le(s, rdp_shareid);
00128         out_uint8(s, 0);        /* pad */
00129         out_uint8(s, 1);        /* streamid */
00130         out_uint16_le(s, (length - 14));
00131         out_uint8(s, data_pdu_type);
00132         out_uint8(s, 0);        /* compress_type */
00133         out_uint16(s, 0);       /* compress_len */
00134 
00135         sec_send(s, encryption ? SEC_ENCRYPT : 0);
00136 }
00137 
00138 /* Output a string in Unicode */
00139 void
00140 rdp_out_unistr(STREAM s, char *string, int len)
00141 {
00142         int i = 0, j = 0;
00143 
00144         len += 2;
00145 
00146         while (i < len)
00147         {
00148                 s->p[i++] = string[j++];
00149                 s->p[i++] = 0;
00150         }
00151 
00152         s->p += len;
00153 }
00154 
00155 /* Parse a logon info packet */
00156 static void
00157 rdp_send_logon_info(uint32 flags, char *domain, char *user,
00158                     char *password, char *program, char *directory)
00159 {
00160         int len_domain = 2 * strlen(domain);
00161         int len_user = 2 * strlen(user);
00162         int len_password = 2 * strlen(password);
00163         int len_program = 2 * strlen(program);
00164         int len_directory = 2 * strlen(directory);
00165         uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
00166         STREAM s;
00167 
00168         s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
00169                      + len_program + len_directory + 10);
00170 
00171         out_uint32(s, 0);
00172         out_uint32_le(s, flags);
00173         out_uint16_le(s, len_domain);
00174         out_uint16_le(s, len_user);
00175         out_uint16_le(s, len_password);
00176         out_uint16_le(s, len_program);
00177         out_uint16_le(s, len_directory);
00178         rdp_out_unistr(s, domain, len_domain);
00179         rdp_out_unistr(s, user, len_user);
00180         rdp_out_unistr(s, password, len_password);
00181         rdp_out_unistr(s, program, len_program);
00182         rdp_out_unistr(s, directory, len_directory);
00183 
00184         s_mark_end(s);
00185         sec_send(s, sec_flags);
00186 }
00187 
00188 /* Send a control PDU */
00189 static void
00190 rdp_send_control(uint16 action)
00191 {
00192         STREAM s;
00193 
00194         s = rdp_init_data(8);
00195 
00196         out_uint16_le(s, action);
00197         out_uint16(s, 0);       /* userid */
00198         out_uint32(s, 0);       /* control id */
00199 
00200         s_mark_end(s);
00201         rdp_send_data(s, RDP_DATA_PDU_CONTROL);
00202 }
00203 
00204 /* Send a synchronisation PDU */
00205 static void
00206 rdp_send_synchronise(void)
00207 {
00208         STREAM s;
00209 
00210         s = rdp_init_data(4);
00211 
00212         out_uint16_le(s, 1);    /* type */
00213         out_uint16_le(s, 1002);
00214 
00215         s_mark_end(s);
00216         rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
00217 }
00218 
00219 /* Send a single input event */
00220 void
00221 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
00222 {
00223         STREAM s;
00224 
00225         s = rdp_init_data(16);
00226 
00227         out_uint16_le(s, 1);    /* number of events */
00228         out_uint16(s, 0);       /* pad */
00229 
00230         out_uint32_le(s, time);
00231         out_uint16_le(s, message_type);
00232         out_uint16_le(s, device_flags);
00233         out_uint16_le(s, param1);
00234         out_uint16_le(s, param2);
00235 
00236         s_mark_end(s);
00237         rdp_send_data(s, RDP_DATA_PDU_INPUT);
00238 }
00239 
00240 /* Send an (empty) font information PDU */
00241 static void
00242 rdp_send_fonts(uint16 seq)
00243 {
00244         STREAM s;
00245 
00246         s = rdp_init_data(8);
00247 
00248         out_uint16(s, 0);       /* number of fonts */
00249         out_uint16_le(s, 0x3e); /* unknown */
00250         out_uint16_le(s, seq);  /* unknown */
00251         out_uint16_le(s, 0x32); /* entry size */
00252 
00253         s_mark_end(s);
00254         rdp_send_data(s, RDP_DATA_PDU_FONT2);
00255 }
00256 
00257 /* Output general capability set */
00258 static void
00259 rdp_out_general_caps(STREAM s)
00260 {
00261         out_uint16_le(s, RDP_CAPSET_GENERAL);
00262         out_uint16_le(s, RDP_CAPLEN_GENERAL);
00263 
00264         out_uint16_le(s, 1);    /* OS major type */
00265         out_uint16_le(s, 3);    /* OS minor type */
00266         out_uint16_le(s, 0x200);        /* Protocol version */
00267         out_uint16(s, 0);       /* Pad */
00268         out_uint16(s, 0);       /* Compression types */
00269         out_uint16(s, 0);       /* Pad */
00270         out_uint16(s, 0);       /* Update capability */
00271         out_uint16(s, 0);       /* Remote unshare capability */
00272         out_uint16(s, 0);       /* Compression level */
00273         out_uint16(s, 0);       /* Pad */
00274 }
00275 
00276 /* Output bitmap capability set */
00277 static void
00278 rdp_out_bitmap_caps(STREAM s)
00279 {
00280         out_uint16_le(s, RDP_CAPSET_BITMAP);
00281         out_uint16_le(s, RDP_CAPLEN_BITMAP);
00282 
00283         out_uint16_le(s, 8);    /* Preferred BPP */
00284         out_uint16_le(s, 1);    /* Receive 1 BPP */
00285         out_uint16_le(s, 1);    /* Receive 4 BPP */
00286         out_uint16_le(s, 1);    /* Receive 8 BPP */
00287         out_uint16_le(s, 800);  /* Desktop width */
00288         out_uint16_le(s, 600);  /* Desktop height */
00289         out_uint16(s, 0);       /* Pad */
00290         out_uint16(s, 0);       /* Allow resize */
00291         out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */
00292         out_uint16(s, 0);       /* Unknown */
00293         out_uint16_le(s, 1);    /* Unknown */
00294         out_uint16(s, 0);       /* Pad */
00295 }
00296 
00297 /* Output order capability set */
00298 static void
00299 rdp_out_order_caps(STREAM s)
00300 {
00301         uint8 order_caps[32];
00302 
00303 
00304         memset(order_caps, 0, 32);
00305         order_caps[0] = 1;      /* dest blt */
00306         order_caps[1] = 1;      /* pat blt */
00307         order_caps[2] = 1;      /* screen blt */
00308 //      order_caps[3] = 1;      /* required for memblt? */
00309         order_caps[8] = 1;      /* line */
00310         order_caps[9] = 1;      /* line */
00311         order_caps[10] = 1;     /* rect */
00312         order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */
00313         order_caps[13] = 1;     /* memblt */
00314         order_caps[14] = 1;     /* triblt */
00315         order_caps[22] = 1;     /* polyline */
00316         order_caps[27] = 1;     /* text2 */
00317         out_uint16_le(s, RDP_CAPSET_ORDER);
00318         out_uint16_le(s, RDP_CAPLEN_ORDER);
00319 
00320         out_uint8s(s, 20);      /* Terminal desc, pad */
00321         out_uint16_le(s, 1);    /* Cache X granularity */
00322         out_uint16_le(s, 20);   /* Cache Y granularity */
00323         out_uint16(s, 0);       /* Pad */
00324         out_uint16_le(s, 1);    /* Max order level */
00325         out_uint16_le(s, 0x147);        /* Number of fonts */
00326         out_uint16_le(s, 0x2a); /* Capability flags */
00327         out_uint8p(s, order_caps, 32);  /* Orders supported */
00328         out_uint16_le(s, 0x6a1);        /* Text capability flags */
00329         out_uint8s(s, 6);       /* Pad */
00330         out_uint32_le(s, desktop_save == False ? 0 : 0x38400);  /* Desktop cache size */
00331 //      out_uint32_le(s, 0); // desktop cache set to 0
00332         out_uint32(s, 0);       /* Unknown */
00333         out_uint32_le(s, 0x4e4);        /* Unknown */
00334 }
00335 
00336 /* Output bitmap cache capability set */
00337 static void
00338 rdp_out_bmpcache_caps(STREAM s)
00339 {
00340         out_uint16_le(s, RDP_CAPSET_BMPCACHE);
00341         out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
00342 
00343         out_uint8s(s, 24);      /* unused */
00344         out_uint16_le(s, 0x258);        /* entries */
00345         out_uint16_le(s, 0x100);        /* max cell size */
00346         out_uint16_le(s, 0x12c);        /* entries */
00347         out_uint16_le(s, 0x400);        /* max cell size */
00348         out_uint16_le(s, 0x106);        /* entries */
00349         out_uint16_le(s, 0x1000);       /* max cell size */
00350 }
00351 
00352 /* Output control capability set */
00353 static void
00354 rdp_out_control_caps(STREAM s)
00355 {
00356         out_uint16_le(s, RDP_CAPSET_CONTROL);
00357         out_uint16_le(s, RDP_CAPLEN_CONTROL);
00358 
00359         out_uint16(s, 0);       /* Control capabilities */
00360         out_uint16(s, 0);       /* Remote detach */
00361         out_uint16_le(s, 2);    /* Control interest */
00362         out_uint16_le(s, 2);    /* Detach interest */
00363 }
00364 
00365 /* Output activation capability set */
00366 static void
00367 rdp_out_activate_caps(STREAM s)
00368 {
00369         out_uint16_le(s, RDP_CAPSET_ACTIVATE);
00370         out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
00371 
00372         out_uint16(s, 0);       /* Help key */
00373         out_uint16(s, 0);       /* Help index key */
00374         out_uint16(s, 0);       /* Extended help key */
00375         out_uint16(s, 0);       /* Window activate */
00376 }
00377 
00378 /* Output pointer capability set */
00379 static void
00380 rdp_out_pointer_caps(STREAM s)
00381 {
00382         out_uint16_le(s, RDP_CAPSET_POINTER);
00383         out_uint16_le(s, RDP_CAPLEN_POINTER);
00384 
00385         out_uint16(s, 0);       /* Colour pointer */
00386         out_uint16_le(s, 20);   /* Cache size */
00387 }
00388 
00389 /* Output share capability set */
00390 static void
00391 rdp_out_share_caps(STREAM s)
00392 {
00393         out_uint16_le(s, RDP_CAPSET_SHARE);
00394         out_uint16_le(s, RDP_CAPLEN_SHARE);
00395 
00396         out_uint16(s, 0);       /* userid */
00397         out_uint16(s, 0);       /* pad */
00398 }
00399 
00400 /* Output colour cache capability set */
00401 static void
00402 rdp_out_colcache_caps(STREAM s)
00403 {
00404         out_uint16_le(s, RDP_CAPSET_COLCACHE);
00405         out_uint16_le(s, RDP_CAPLEN_COLCACHE);
00406 
00407         out_uint16_le(s, 6);    /* cache size */
00408         out_uint16(s, 0);       /* pad */
00409 }
00410 
00411 static uint8 canned_caps[] = {
00412         0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
00413         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
00414         0x00, 0x00, 0x00, 0x00, 0x00,
00415         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00416         0x00, 0x00, 0x00, 0x00, 0x00,
00417         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00418         0x00, 0x00, 0x00, 0x00, 0x00,
00419         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00420         0x00, 0x00, 0x00, 0x00, 0x00,
00421         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00422         0x0C, 0x00, 0x08, 0x00, 0x01,
00423         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
00424         0x10, 0x00, 0x34, 0x00, 0xFE,
00425         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
00426         0xFE, 0x00, 0x08, 0x00, 0xFE,
00427         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
00428         0xFE, 0x00, 0x80, 0x00, 0xFE,
00429         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
00430         0x02, 0x00, 0x00, 0x00
00431 };
00432 
00433 /* Output unknown capability set */
00434 static void
00435 rdp_out_unknown_caps(STREAM s)
00436 {
00437         out_uint16_le(s, RDP_CAPSET_UNKNOWN);
00438         out_uint16_le(s, 0x58);
00439 
00440         out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
00441 }
00442 
00443 /* Send a confirm active PDU */
00444 static void
00445 rdp_send_confirm_active(void)
00446 {
00447         STREAM s;
00448         uint16 caplen =
00449                 RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
00450                 RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
00451                 RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
00452                 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
00453 
00454         s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));
00455 
00456         out_uint32_le(s, rdp_shareid);
00457         out_uint16_le(s, 0x3ea);        /* userid */
00458         out_uint16_le(s, sizeof(RDP_SOURCE));
00459         out_uint16_le(s, caplen);
00460 
00461         out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
00462         out_uint16_le(s, 0xd);  /* num_caps */
00463         out_uint8s(s, 2);       /* pad */
00464 
00465         rdp_out_general_caps(s);
00466         rdp_out_bitmap_caps(s);
00467         rdp_out_order_caps(s);
00468         rdp_out_bmpcache_caps(s);
00469         rdp_out_colcache_caps(s);
00470         rdp_out_activate_caps(s);
00471         rdp_out_control_caps(s);
00472         rdp_out_pointer_caps(s);
00473         rdp_out_share_caps(s);
00474         rdp_out_unknown_caps(s);
00475 
00476         s_mark_end(s);
00477         rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);
00478 }
00479 
00480 /* Respond to a demand active PDU */
00481 void
00482 process_demand_active(STREAM s)
00483 {
00484         uint8 type;
00485 
00486         in_uint32_le(s, rdp_shareid);
00487 
00488         DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
00489 
00490         rdp_send_confirm_active();
00491         rdp_send_synchronise();
00492         rdp_send_control(RDP_CTL_COOPERATE);
00493         rdp_send_control(RDP_CTL_REQUEST_CONTROL);
00494         rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
00495         rdp_recv(&type);        /* RDP_CTL_COOPERATE */
00496         rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
00497         rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
00498         rdp_send_fonts(1);
00499         rdp_send_fonts(2);
00500         rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
00501         reset_order_state();
00502 }
00503 
00504 /* Process a pointer PDU */
00505 static void
00506 process_pointer_pdu(STREAM s)
00507 {
00508         uint16 message_type;
00509         uint16 x, y, width, height, cache_idx, masklen, datalen;
00510         uint8 *mask, *data;
00511         HCURSOR cursor;
00512 
00513         in_uint16_le(s, message_type);
00514         in_uint8s(s, 2);        /* pad */
00515 
00516         switch (message_type)
00517         {
00518                 case RDP_POINTER_MOVE:
00519                         in_uint16_le(s, x);
00520                         in_uint16_le(s, y);
00521                         if (s_check(s))
00522                                 ui_move_pointer(x, y);
00523                         break;
00524 
00525                 case RDP_POINTER_COLOR:
00526                         in_uint16_le(s, cache_idx);
00527                         in_uint16_le(s, x);
00528                         in_uint16_le(s, y);
00529                         in_uint16_le(s, width);
00530                         in_uint16_le(s, height);
00531                         in_uint16_le(s, masklen);
00532                         in_uint16_le(s, datalen);
00533                         in_uint8p(s, data, datalen);
00534                         in_uint8p(s, mask, masklen);
00535                         cursor = ui_create_cursor(x, y, width, height, mask, data);
00536                         ui_set_cursor(cursor);
00537                         cache_put_cursor(cache_idx, cursor);
00538                         break;
00539 
00540                 case RDP_POINTER_CACHED:
00541                         in_uint16_le(s, cache_idx);
00542                         ui_set_cursor(cache_get_cursor(cache_idx));
00543                         break;
00544 
00545                 default:
00546                         DEBUG(("Pointer message 0x%x\n", message_type));
00547         }
00548 }
00549 
00550 /* Process bitmap updates */
00551 static void
00552 process_bitmap_updates(STREAM s)
00553 {
00554         uint16 num_updates;
00555         uint16 left, top, right, bottom, width, height;
00556         uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
00557         uint8 *data, *bmpdata;
00558         int i;
00559 
00560    in_uint16_le(s, num_updates);
00561 
00562         for (i = 0; i < num_updates; i++)
00563         {
00564                 in_uint16_le(s, left);
00565                 in_uint16_le(s, top);
00566                 in_uint16_le(s, right);
00567                 in_uint16_le(s, bottom);
00568                 in_uint16_le(s, width);
00569                 in_uint16_le(s, height);
00570                 in_uint16_le(s, bpp);
00571                 Bpp = (bpp + 7) / 8;
00572                 in_uint16_le(s, compress);
00573                 in_uint16_le(s, bufsize);
00574 
00575                 cx = right - left + 1;
00576                 cy = bottom - top + 1;
00577 
00578                 DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",
00579                        left, top, right, bottom, width, height, compress));
00580 
00581                 if (!compress)
00582                 {
00583                         int y;
00584                         bmpdata = (uint8*)xmalloc(width * height * Bpp);
00585                         for (y = 0; y < height; y++)
00586                         {
00587                                 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
00588                                           width * Bpp);
00589                         }
00590                         ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
00591                         xfree(bmpdata);
00592                         continue;
00593                 }
00594 
00595                 in_uint8s(s, 2);        /* pad */
00596                 in_uint16_le(s, size);
00597                 in_uint8s(s, 4);        /* line_size, final_size */
00598                 in_uint8p(s, data, size);
00599                 bmpdata = (uint8*)xmalloc(width * height * Bpp);
00600                 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
00601                 {
00602                         ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
00603                 }
00604                 xfree(bmpdata);
00605         }
00606 }
00607 
00608 /* Process a palette update */
00609 static void
00610 process_palette(STREAM s)
00611 {
00612         COLOURENTRY *entry;
00613         COLOURMAP map;
00614         HCOLOURMAP hmap;
00615         int i;
00616    uint8 data[1536];
00617 
00618         in_uint8s(s, 2);        /* pad */
00619         in_uint16_le(s, map.ncolours);
00620         in_uint8s(s, 2);        /* pad */
00621 
00622         map.colours = (COLOURENTRY*)data;
00623 
00624         for (i = 0; i < map.ncolours; i++)
00625         {
00626                 entry = &map.colours[i];
00627                 in_uint8(s, entry->red);
00628                 in_uint8(s, entry->green);
00629                 in_uint8(s, entry->blue);
00630         }
00631         hmap = ui_create_colourmap(&map);
00632         ui_set_colourmap(hmap);
00633 }
00634 
00635 /* Process an update PDU */
00636 static void
00637 process_update_pdu(STREAM s)
00638 {
00639         uint16 update_type;
00640 
00641         in_uint16_le(s, update_type);
00642         ui_begin_update();
00643         switch (update_type)
00644         {
00645                 case RDP_UPDATE_ORDERS:
00646                         process_orders(s);
00647                         break;
00648 
00649                 case RDP_UPDATE_BITMAP:
00650                         process_bitmap_updates(s);
00651                         break;
00652 
00653                 case RDP_UPDATE_PALETTE:
00654                         process_palette(s);
00655                         break;
00656 
00657                 case RDP_UPDATE_SYNCHRONIZE:
00658                         break;
00659 
00660                 default:
00661                         unimpl("update %d\n", update_type);
00662         }
00663         ui_end_update();
00664 }
00665 
00666 /* Process data PDU */
00667 void
00668 process_data_pdu(STREAM s)
00669 {
00670         uint8 data_pdu_type;
00671 
00672         in_uint8s(s, 8);        /* shareid, pad, streamid, length */
00673         in_uint8(s, data_pdu_type);
00674         in_uint8s(s, 3);        /* compress_type, compress_len */
00675 
00676         switch (data_pdu_type)
00677         {
00678                 case RDP_DATA_PDU_UPDATE:
00679                         process_update_pdu(s);
00680                         break;
00681 
00682                 case RDP_DATA_PDU_POINTER:
00683                         process_pointer_pdu(s);
00684                         break;
00685 
00686                 case RDP_DATA_PDU_BELL:
00687                         ui_bell();
00688                         break;
00689 
00690                 case RDP_DATA_PDU_LOGON:
00691                         /* User logged on */
00692                         break;
00693 
00694                 default:
00695                         unimpl("data PDU %d\n", data_pdu_type);
00696         }
00697 }
00698 
00699 /* Process incoming packets */
00700 BOOL
00701 rdp_main_loop(void)
00702 {
00703         uint8 type;
00704         STREAM s;
00705         BOOL cont = True;
00706         while (cont)
00707         {
00708                 s = rdp_recv(&type);
00709                 if (s == NULL)
00710                         return False;
00711                 switch (type)
00712                 {
00713                         case RDP_PDU_DEMAND_ACTIVE:
00714                                 process_demand_active(s);
00715                                 break;
00716                         case RDP_PDU_DEACTIVATE:
00717                                 break;
00718                         case RDP_PDU_DATA:
00719                                 process_data_pdu(s);
00720                                 break;
00721                         case 0:
00722                                 break;
00723                         default:
00724                                 unimpl("PDU %d\n", type);
00725                 }
00726                 cont = next_packet < s->end;
00727         }
00728         return True;
00729 }
00730 
00731 /* Establish a connection up to the RDP layer */
00732 BOOL
00733 rdp_connect(char *server, uint32 flags, char *domain, char *password,
00734             char *command, char *directory)
00735 {
00736         if (!sec_connect(server))
00737                 return False;
00738 
00739         rdp_send_logon_info(flags, domain, username, password, command, directory);
00740         return True;
00741 }
00742 
00743 /* Disconnect from the RDP layer */
00744 void
00745 rdp_disconnect(void)
00746 {
00747         sec_disconnect();
00748 }

Generated on Sat Nov 5 16:17:42 2005 for OPIE by  doxygen 1.4.2