1 /* -*- c-basic-offset: 8 -*- 2 rdesktop: A Remote Desktop Protocol client. 3 Protocol services - RDP5 short form PDU processing 4 Copyright (C) Matthew Chapman 1999-2005 5 Copyright (C) Erik Forsberg 2003 6 7 This program is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 This program is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with this program; if not, write to the Free Software Foundation, Inc., 19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 */ 21 22 #include "rdesktop.h" 23 24 BOOL 25 rdp5_process(RDPCLIENT * This, STREAM s) 26 { 27 uint16 length, count, x, y; 28 uint8 type, ctype; 29 uint8 *next; 30 31 uint32 roff, rlen; 32 struct stream *ns = &(This->mppc_dict.ns); 33 struct stream *ts; 34 35 #if 0 36 printf("RDP5 data:\n"); 37 hexdump(s->p, s->end - s->p); 38 #endif 39 40 ui_begin_update(This); 41 while (s->p < s->end) 42 { 43 in_uint8(s, type); 44 if (type & RDP5_COMPRESSED) 45 { 46 in_uint8(s, ctype); 47 in_uint16_le(s, length); 48 type ^= RDP5_COMPRESSED; 49 } 50 else 51 { 52 ctype = 0; 53 in_uint16_le(s, length); 54 } 55 This->next_packet = next = s->p + length; 56 57 if (ctype & RDP_MPPC_COMPRESSED) 58 { 59 void * p; 60 61 if (mppc_expand(This, s->p, length, ctype, &roff, &rlen) == -1) 62 error("error while decompressing packet\n"); 63 64 /* allocate memory and copy the uncompressed data into the temporary stream */ 65 p = realloc(ns->data, rlen); 66 67 if(p == NULL) 68 { 69 This->disconnect_reason = 262; 70 return False; 71 } 72 73 ns->data = (uint8 *) p; 74 75 memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen); 76 77 ns->size = rlen; 78 ns->end = (ns->data + ns->size); 79 ns->p = ns->data; 80 ns->rdp_hdr = ns->p; 81 82 ts = ns; 83 } 84 else 85 ts = s; 86 87 switch (type) 88 { 89 case 0: /* update orders */ 90 in_uint16_le(ts, count); 91 process_orders(This, ts, count); 92 break; 93 case 1: /* update bitmap */ 94 in_uint8s(ts, 2); /* part length */ 95 process_bitmap_updates(This, ts); 96 break; 97 case 2: /* update palette */ 98 in_uint8s(ts, 2); /* uint16 = 2 */ 99 process_palette(This, ts); 100 break; 101 case 3: /* update synchronize */ 102 break; 103 case 5: /* null pointer */ 104 ui_set_null_cursor(This); 105 break; 106 case 6: /* default pointer */ 107 break; 108 case 8: /* pointer position */ 109 in_uint16_le(ts, x); 110 in_uint16_le(ts, y); 111 if (s_check(ts)) 112 ui_move_pointer(This, x, y); 113 break; 114 case 9: /* color pointer */ 115 process_colour_pointer_pdu(This, ts); 116 break; 117 case 10: /* cached pointer */ 118 process_cached_pointer_pdu(This, ts); 119 break; 120 default: 121 unimpl("RDP5 opcode %d\n", type); 122 } 123 124 s->p = next; 125 } 126 ui_end_update(This); 127 return True; 128 } 129