/[rdesktop]/sourceforge.net/trunk/rdesktop/process.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

Contents of /sourceforge.net/trunk/rdesktop/process.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (show annotations)
Tue Jul 25 12:34:29 2000 UTC (23 years, 9 months ago) by matty
File MIME type: text/plain
File size: 13475 byte(s)
Committing some awesome progress I made while overseas - this commit
really embodies a huge number of changes. We are now able to talk quite
fluently to a French NT Terminal Server - in normal usage only minor
font issues remain (handling of TEXT2 order is not perfect).

The next major hurdle is encryption, and it will be quite a big hurdle
- there seems to be some quite nasty session key stuff.

1 /*
2 rdesktop: A Remote Desktop Protocol client.
3 RDP message processing
4 Copyright (C) Matthew Chapman 1999-2000
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /* Process incoming packets */
24 void rdp_main_loop(HCONN conn)
25 {
26 RDP_DATA_HEADER hdr;
27 RDP_ORDER_STATE os;
28 uint8 type;
29
30 memset(&os, 0, sizeof(os));
31
32 while (rdp_recv_pdu(conn, &type))
33 {
34 switch (type)
35 {
36 case RDP_PDU_DEMAND_ACTIVE:
37 process_demand_active(conn);
38 memset(&os, 0, sizeof(os));
39 break;
40
41 case RDP_PDU_DEACTIVATE:
42 break;
43
44 case RDP_PDU_DATA:
45 rdp_io_data_header(&conn->in, &hdr);
46
47 switch (hdr.data_pdu_type)
48 {
49 case RDP_DATA_PDU_UPDATE:
50 process_update_pdu(conn, &os);
51 break;
52
53 case RDP_DATA_PDU_POINTER:
54 process_pointer_pdu(conn);
55 break;
56
57 default:
58 NOTIMP("data PDU 0x%x\n",
59 hdr.data_pdu_type);
60 }
61 break;
62
63 default:
64 NOTIMP("PDU 0x%x\n", type);
65 }
66 }
67 }
68
69 /* Respond to a demand active PDU */
70 void process_demand_active(HCONN conn)
71 {
72 RDP_ACTIVE_PDU active;
73 uint8 type;
74
75 if (!rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE))
76 return;
77
78 DEBUG("DEMAND_ACTIVE(id=0x%x)\n", active.shareid);
79
80 rdp_send_confirm_active(conn, active.shareid, 640, 480);
81 rdp_send_synchronize(conn);
82 rdp_send_control(conn, RDP_CTL_COOPERATE);
83 rdp_send_control(conn, RDP_CTL_REQUEST_CONTROL);
84 rdp_recv_pdu(conn, &type); // RDP_PDU_SYNCHRONIZE
85 rdp_recv_pdu(conn, &type); // RDP_CTL_COOPERATE
86 rdp_recv_pdu(conn, &type); // RDP_CTL_GRANT_CONTROL
87 rdp_send_input(conn, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
88 rdp_send_fonts(conn, 1);
89 rdp_send_fonts(conn, 2);
90 rdp_recv_pdu(conn, &type); // RDP_PDU_UNKNOWN 0x28
91 }
92
93 /* Process a pointer PDU */
94 void process_pointer_pdu(HCONN conn)
95 {
96 RDP_POINTER_PDU pp;
97
98 if (!rdp_io_pointer_pdu(&conn->in, &pp))
99 return;
100
101 switch (pp.message)
102 {
103 case RDP_POINTER_MOVE:
104 ui_move_pointer(conn->wnd, pp.x, pp.y);
105 break;
106
107 default:
108 NOTIMP("pointer message 0x%x\n", pp.message);
109 }
110 }
111
112 /* Process an update PDU */
113 void process_update_pdu(HCONN conn, RDP_ORDER_STATE *os)
114 {
115 RDP_UPDATE_PDU update;
116
117 if (!rdp_io_update_pdu(&conn->in, &update))
118 return;
119
120 switch (update.update_type)
121 {
122 case RDP_UPDATE_ORDERS:
123 process_orders(conn, os);
124 break;
125
126 case RDP_UPDATE_PALETTE:
127 case RDP_UPDATE_SYNCHRONIZE:
128 break;
129
130 default:
131 NOTIMP("update 0x%x\n", update.update_type);
132 }
133
134 }
135
136
137 /* UPDATE PDUs */
138
139 /* Process an order */
140 void process_orders(HCONN conn, RDP_ORDER_STATE *os)
141 {
142 RDP_SECONDARY_ORDER rso;
143 uint32 present, num_orders;
144 uint8 order_flags;
145 int size, processed = 0;
146 BOOL delta;
147
148 lsb_io_uint32(&conn->in, &num_orders);
149 num_orders &= 0xffff; /* second word padding */
150
151 while (processed < num_orders)
152 {
153 if (!prs_io_uint8(&conn->in, &order_flags))
154 break;
155
156 if (!(order_flags & RDP_ORDER_STANDARD))
157 {
158 ERROR("Order parsing failed\n");
159 return;
160 }
161
162 if (order_flags & RDP_ORDER_SECONDARY)
163 {
164 if (!rdp_io_secondary_order(&conn->in, &rso))
165 break;
166
167 switch (rso.type)
168 {
169 case RDP_ORDER_RAW_BMPCACHE:
170 process_raw_bmpcache(conn);
171 break;
172
173 case RDP_ORDER_COLCACHE:
174 process_colcache(conn);
175 break;
176
177 case RDP_ORDER_BMPCACHE:
178 process_bmpcache(conn);
179 break;
180
181 case RDP_ORDER_FONTCACHE:
182 process_fontcache(conn);
183 break;
184
185 default:
186 NOTIMP("secondary order %d\n",
187 rso.type);
188 conn->in.offset += rso.length + 7;
189 }
190 }
191 else
192 {
193 if (order_flags & RDP_ORDER_CHANGE)
194 {
195 prs_io_uint8(&conn->in, &os->order_type);
196 }
197
198 switch (os->order_type)
199 {
200 case RDP_ORDER_TRIBLT:
201 case RDP_ORDER_TEXT2:
202 size = 3;
203 break;
204
205 case RDP_ORDER_PATBLT:
206 case RDP_ORDER_MEMBLT:
207 case RDP_ORDER_LINE:
208 size = 2;
209 break;
210
211 default:
212 size = 1;
213 }
214
215 rdp_io_present(&conn->in, &present, order_flags, size);
216
217 if (order_flags & RDP_ORDER_BOUNDS)
218 {
219 if (!(order_flags & RDP_ORDER_LASTBOUNDS))
220 rdp_io_bounds(&conn->in, &os->bounds);
221
222 ui_set_clip(conn->wnd, os->bounds.left,
223 os->bounds.top,
224 os->bounds.right - os->bounds.left + 1,
225 os->bounds.bottom - os->bounds.top + 1);
226 }
227
228 delta = order_flags & RDP_ORDER_DELTA;
229
230 switch (os->order_type)
231 {
232 case RDP_ORDER_DESTBLT:
233 process_destblt(conn, &os->destblt,
234 present, delta);
235 break;
236
237 case RDP_ORDER_PATBLT:
238 process_patblt(conn, &os->patblt,
239 present, delta);
240 break;
241
242 case RDP_ORDER_SCREENBLT:
243 process_screenblt(conn, &os->screenblt,
244 present, delta);
245 break;
246
247 case RDP_ORDER_LINE:
248 process_line(conn, &os->line,
249 present, delta);
250 break;
251
252 case RDP_ORDER_RECT:
253 process_rect(conn, &os->rect,
254 present, delta);
255 break;
256
257 case RDP_ORDER_DESKSAVE:
258 process_desksave(conn, &os->desksave,
259 present, delta);
260 break;
261
262 case RDP_ORDER_MEMBLT:
263 process_memblt(conn, &os->memblt,
264 present, delta);
265 break;
266
267 case RDP_ORDER_TRIBLT:
268 process_triblt(conn, &os->triblt,
269 present, delta);
270 break;
271
272 case RDP_ORDER_TEXT2:
273 process_text2(conn, &os->text2,
274 present, delta);
275 break;
276
277 default:
278 NOTIMP("order %d\n", os->order_type);
279 return;
280 }
281
282 if (order_flags & RDP_ORDER_BOUNDS)
283 ui_reset_clip(conn->wnd);
284 }
285
286 processed++;
287 }
288
289 if (conn->in.offset != conn->in.rdp_offset)
290 WARN("Order data remaining\n");
291 }
292
293
294 /* PRIMARY ORDERS */
295
296 /* Process a destination blt order */
297 void process_destblt(HCONN conn, DESTBLT_ORDER *os, uint32 present, BOOL delta)
298 {
299 if (!rdp_io_destblt_order(&conn->in, os, present, delta))
300 return;
301
302 DEBUG("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n",
303 os->opcode, os->x, os->y, os->cx, os->cy);
304
305 ui_destblt(conn->wnd, ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy);
306 }
307
308 /* Process a pattern blt order */
309 void process_patblt(HCONN conn, PATBLT_ORDER *os, uint32 present, BOOL delta)
310 {
311 if (!rdp_io_patblt_order(&conn->in, os, present, delta))
312 return;
313
314 DEBUG("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
315 os->opcode, os->x, os->y, os->cx, os->cy,
316 os->brush.style, os->bgcolour, os->fgcolour);
317
318 ui_patblt(conn->wnd, ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy,
319 &os->brush, os->bgcolour, os->fgcolour);
320 }
321
322 /* Process a screen blt order */
323 void process_screenblt(HCONN conn, SCREENBLT_ORDER *os, uint32 present, BOOL delta)
324 {
325 if (!rdp_io_screenblt_order(&conn->in, os, present, delta))
326 return;
327
328 DEBUG("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n",
329 os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy);
330
331 ui_screenblt(conn->wnd, ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy,
332 os->srcx, os->srcy);
333 }
334
335 /* Process a line order */
336 void process_line(HCONN conn, LINE_ORDER *os, uint32 present, BOOL delta)
337 {
338 if (!rdp_io_line_order(&conn->in, os, present, delta))
339 return;
340
341 DEBUG("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dx=%d,fg=0x%x)\n",
342 os->opcode, os->startx, os->starty, os->endx, os->endy,
343 os->pen.colour);
344
345 if (os->opcode < 0x01 || os->opcode > 0x10)
346 {
347 ERROR("Bad ROP2 opcode 0x%x\n", os->opcode);
348 return;
349 }
350
351 ui_line(conn->wnd, os->opcode-1, os->startx, os->starty,
352 os->endx, os->endy, &os->pen);
353 }
354
355 /* Process an opaque rectangle order */
356 void process_rect(HCONN conn, RECT_ORDER *os, uint32 present, BOOL delta)
357 {
358 if (!rdp_io_rect_order(&conn->in, os, present, delta))
359 return;
360
361 DEBUG("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n",
362 os->x, os->y, os->cx, os->cy, os->colour);
363
364 ui_rect(conn->wnd, os->x, os->y, os->cx, os->cy, os->colour);
365 }
366
367 /* Process a desktop save order */
368 void process_desksave(HCONN conn, DESKSAVE_ORDER *os, uint32 present, BOOL delta)
369 {
370 int width, height;
371 uint8 *data;
372
373 if (!rdp_io_desksave_order(&conn->in, os, present, delta))
374 return;
375
376 DEBUG("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n",
377 os->left, os->top, os->right, os->bottom, os->offset,
378 os->action);
379
380 data = conn->deskcache + os->offset;
381 width = os->right - os->left + 1;
382 height = os->bottom - os->top + 1;
383
384 if (os->action == 0)
385 {
386 ui_desktop_save(conn->wnd, data, os->left, os->top,
387 width, height);
388 }
389 else
390 {
391 ui_desktop_restore(conn->wnd, data, os->left, os->top,
392 width, height);
393 }
394 }
395
396 /* Process a memory blt order */
397 void process_memblt(HCONN conn, MEMBLT_ORDER *os, uint32 present, BOOL delta)
398 {
399 HBITMAP bitmap;
400
401 if (!rdp_io_memblt_order(&conn->in, os, present, delta))
402 return;
403
404 DEBUG("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n",
405 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id,
406 os->cache_idx);
407
408 bitmap = cache_get_bitmap(conn, os->cache_id, os->cache_idx);
409 if (bitmap == NULL)
410 return;
411
412 ui_memblt(conn->wnd, ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy,
413 bitmap, os->srcx, os->srcy);
414 }
415
416 /* Process a 3-way blt order */
417 void process_triblt(HCONN conn, TRIBLT_ORDER *os, uint32 present, BOOL delta)
418 {
419 HBITMAP bitmap;
420
421 if (!rdp_io_triblt_order(&conn->in, os, present, delta))
422 return;
423
424 DEBUG("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n",
425 os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id,
426 os->cache_idx, os->brush.style, os->bgcolour, os->fgcolour);
427
428 bitmap = cache_get_bitmap(conn, os->cache_id, os->cache_idx);
429 if (bitmap == NULL)
430 return;
431
432 ui_triblt(conn->wnd, os->opcode, os->x, os->y, os->cx, os->cy,
433 bitmap, os->srcx, os->srcy,
434 &os->brush, os->bgcolour, os->fgcolour);
435 }
436
437 /* Process a text order */
438 void process_text2(HCONN conn, TEXT2_ORDER *os, uint32 present, BOOL delta)
439 {
440 BLOB *entry;
441 int i;
442
443 if (!rdp_io_text2_order(&conn->in, os, present, delta))
444 return;
445
446 DEBUG("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,bb=%d,br=%d,fg=0x%x,bg=0x%x,font=%d,fl=0x%x,mix=%d,unk=0x%x,n=%d)\n",
447 os->x, os->y, os->clipleft, os->cliptop, os->clipright,
448 os->clipbottom, os->boxleft, os->boxtop, os->boxright,
449 os->boxbottom, os->fgcolour, os->bgcolour, os->font,
450 os->flags, os->mixmode, os->unknown, os->length);
451
452 fprintf(stderr, "Text: ");
453
454 for (i = 0; i < os->length; i++)
455 fprintf(stderr, "%02x ", os->text[i]);
456
457 fprintf(stderr, "\n");
458
459 /* Process special cache strings */
460 if ((os->length == 2) && (os->text[0] == 0xfe))
461 {
462 entry = cache_get_text(conn, os->text[1]);
463
464 if (entry == NULL)
465 return;
466
467 memcpy(os->text, entry->data, entry->size);
468 os->length = entry->size;
469 }
470 else if ((os->length >= 3) && (os->text[os->length-3] == 0xff))
471 {
472 os->length -= 3;
473 cache_put_text(conn, os->text[os->length+1],
474 os->text, os->length);
475 }
476
477 ui_draw_text(conn->wnd, os->font, os->flags, os->mixmode,
478 os->x, os->y, os->boxleft, os->boxtop,
479 os->boxright - os->boxleft,
480 os->boxbottom - os->boxtop,
481 os->bgcolour, os->fgcolour, os->text, os->length);
482 }
483
484
485 /* SECONDARY ORDERS */
486
487 /* Process a raw bitmap cache order */
488 void process_raw_bmpcache(HCONN conn)
489 {
490 RDP_RAW_BMPCACHE_ORDER order;
491 HBITMAP bitmap;
492
493 if (!rdp_io_raw_bmpcache_order(&conn->in, &order))
494 return;
495
496 DEBUG("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n",
497 order.width, order.height, order.cache_id, order.cache_idx);
498
499 bitmap = ui_create_bitmap(conn->wnd, order.width, order.height,
500 order.data);
501 cache_put_bitmap(conn, order.cache_id, order.cache_idx, bitmap);
502 }
503
504 /* Process a bitmap cache order */
505 void process_bmpcache(HCONN conn)
506 {
507 RDP_BMPCACHE_ORDER order;
508 HBITMAP bitmap;
509 char *bmpdata;
510
511 if (!rdp_io_bmpcache_order(&conn->in, &order))
512 return;
513
514 DEBUG("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n",
515 order.width, order.height, order.cache_id, order.cache_idx);
516
517 bmpdata = malloc(order.width * order.height);
518
519 if (bitmap_decompress(bmpdata, order.width, order.height,
520 order.data, order.size))
521 {
522 bitmap = ui_create_bitmap(conn->wnd, order.width, order.height,
523 bmpdata);
524 cache_put_bitmap(conn, order.cache_id, order.cache_idx, bitmap);
525 }
526
527 free(bmpdata);
528 }
529
530 /* Process a colourmap cache order */
531 void process_colcache(HCONN conn)
532 {
533 RDP_COLCACHE_ORDER order;
534 HCOLOURMAP map;
535
536 if (!rdp_io_colcache_order(&conn->in, &order))
537 return;
538
539 DEBUG("COLCACHE(id=%d,n=%d)\n", order.cache_id, order.map.ncolours);
540
541 map = ui_create_colourmap(conn->wnd, &order.map);
542 ui_set_colourmap(conn->wnd, map);
543 }
544
545 /* Process a font cache order */
546 void process_fontcache(HCONN conn)
547 {
548 RDP_FONTCACHE_ORDER order;
549 RDP_FONT_GLYPH *glyph;
550 HGLYPH bitmap;
551 int i;
552
553 if (!rdp_io_fontcache_order(&conn->in, &order))
554 return;
555
556 DEBUG("FONTCACHE(font=%d,n=%d)\n", order.font, order.nglyphs);
557
558 for (i = 0; i < order.nglyphs; i++)
559 {
560 glyph = &order.glyphs[i];
561
562 bitmap = ui_create_glyph(conn->wnd, glyph->width,
563 glyph->height, glyph->data);
564
565 cache_put_font(conn, order.font, glyph->character,
566 glyph->baseline, glyph->width, glyph->height,
567 bitmap);
568 }
569 }

  ViewVC Help
Powered by ViewVC 1.1.26