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 <matthewc.unsw.edu.au> 1999-2008 5 Copyright 2003-2008 Erik Forsberg <forsberg@cendio.se> for Cendio AB 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 3 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 18 along with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #include "precomp.h" 22 23 extern uint8 *g_next_packet; 24 25 extern RDPCOMP g_mppc_dict; 26 27 void 28 rdp5_process(STREAM s) 29 { 30 uint16 length, count, x, y; 31 uint8 type, ctype; 32 uint8 *next; 33 34 uint32 roff, rlen; 35 struct stream *ns = &(g_mppc_dict.ns); 36 struct stream *ts; 37 38 #if 0 39 printf("RDP5 data:\n"); 40 hexdump(s->p, s->end - s->p); 41 #endif 42 43 ui_begin_update(); 44 while (s->p < s->end) 45 { 46 in_uint8(s, type); 47 if (type & RDP5_COMPRESSED) 48 { 49 in_uint8(s, ctype); 50 in_uint16_le(s, length); 51 type ^= RDP5_COMPRESSED; 52 } 53 else 54 { 55 ctype = 0; 56 in_uint16_le(s, length); 57 } 58 g_next_packet = next = s->p + length; 59 60 if (ctype & RDP_MPPC_COMPRESSED) 61 { 62 if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1) 63 error("error while decompressing packet\n"); 64 65 /* allocate memory and copy the uncompressed data into the temporary stream */ 66 ns->data = (uint8 *) xrealloc(ns->data, rlen); 67 68 memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen); 69 70 ns->size = rlen; 71 ns->end = (ns->data + ns->size); 72 ns->p = ns->data; 73 ns->rdp_hdr = ns->p; 74 75 ts = ns; 76 } 77 else 78 ts = s; 79 80 switch (type) 81 { 82 case 0: /* update orders */ 83 in_uint16_le(ts, count); 84 process_orders(ts, count); 85 break; 86 case 1: /* update bitmap */ 87 in_uint8s(ts, 2); /* part length */ 88 process_bitmap_updates(ts); 89 break; 90 case 2: /* update palette */ 91 in_uint8s(ts, 2); /* uint16 = 2 */ 92 process_palette(ts); 93 break; 94 case 3: /* update synchronize */ 95 break; 96 case 5: /* null pointer */ 97 ui_set_null_cursor(); 98 break; 99 case 6: /* default pointer */ 100 break; 101 case 8: /* pointer position */ 102 in_uint16_le(ts, x); 103 in_uint16_le(ts, y); 104 if (s_check(ts)) 105 ui_move_pointer(x, y); 106 break; 107 case 9: /* color pointer */ 108 process_colour_pointer_pdu(ts); 109 break; 110 case 10: /* cached pointer */ 111 process_cached_pointer_pdu(ts); 112 break; 113 case 11: 114 process_new_pointer_pdu(ts); 115 break; 116 default: 117 unimpl("RDP5 opcode %d\n", type); 118 } 119 120 s->p = next; 121 } 122 ui_end_update(); 123 } 124