/[rdesktop]/jpeg/rdesktop/trunk/channels.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

Annotation of /jpeg/rdesktop/trunk/channels.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 473 - (hide annotations)
Sat Sep 27 12:14:25 2003 UTC (20 years, 7 months ago) by forsberg
Original Path: sourceforge.net/trunk/rdesktop/channels.c
File MIME type: text/plain
File size: 4828 byte(s)
If the channel has the CHANNEL_OPTION_SHOW_PROTOCOL set, the flags in
continuation packets must have the flag as well, not only the first packet.

1 forsberg 400 /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.
3 matthewc 432 Protocol services - Virtual channels
4 forsberg 400 Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
5 matthewc 432 Copyright (C) Matthew Chapman 2003
6 forsberg 400
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
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     */
21    
22     #include "rdesktop.h"
23    
24 matthewc 432 #define MAX_CHANNELS 4
25     #define CHANNEL_CHUNK_LENGTH 1600
26     #define CHANNEL_FLAG_FIRST 0x01
27     #define CHANNEL_FLAG_LAST 0x02
28     #define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
29 forsberg 400
30 jsorg71 438 extern BOOL g_use_rdp5;
31 jsorg71 437 extern BOOL g_encryption;
32 forsberg 400
33 matthewc 432 VCHANNEL g_channels[MAX_CHANNELS];
34     unsigned int g_num_channels;
35    
36     /* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5
37 jsorg71 438 channels to MCS channels.
38 forsberg 419
39 matthewc 432 The format of TAG_SRV_CHANNELS seems to be
40 forsberg 419
41     global_channel_no (uint16le)
42     number_of_other_channels (uint16le)
43     ..followed by uint16les for the other channels.
44     */
45    
46 matthewc 432 VCHANNEL *
47     channel_register(char *name, uint32 flags, void (*callback) (STREAM))
48 forsberg 400 {
49 matthewc 432 VCHANNEL *channel;
50    
51 jsorg71 438 if (!g_use_rdp5)
52 matthewc 432 return NULL;
53    
54     if (g_num_channels >= MAX_CHANNELS)
55 forsberg 400 {
56 matthewc 432 error("Channel table full, increase MAX_CHANNELS\n");
57     return NULL;
58 forsberg 400 }
59 matthewc 432
60     channel = &g_channels[g_num_channels];
61     channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
62     strncpy(channel->name, name, 8);
63     channel->flags = flags;
64     channel->process = callback;
65     g_num_channels++;
66     return channel;
67 forsberg 400 }
68    
69 matthewc 432 STREAM
70 astrand 435 channel_init(VCHANNEL * channel, uint32 length)
71 forsberg 400 {
72 matthewc 432 STREAM s;
73    
74 jsorg71 437 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
75 matthewc 432 s_push_layer(s, channel_hdr, 8);
76     return s;
77     }
78    
79     void
80 astrand 435 channel_send(STREAM s, VCHANNEL * channel)
81 matthewc 432 {
82     uint32 length, flags;
83     uint32 thislength, remaining;
84     char *data;
85    
86     /* first fragment sent in-place */
87     s_pop_layer(s, channel_hdr);
88     length = s->end - s->p - 8;
89    
90 forsberg 473 DEBUG_CLIPBOARD(("channel_send, length = %d\n", length));
91    
92     thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
93     /* Note: In the original clipboard implementation, this number was
94     1592, not 1600. However, I don't remember the reason and 1600 seems
95     to work so.. This applies only to *this* length, not the length of
96     continuation or ending packets. */
97 matthewc 432 remaining = length - thislength;
98 astrand 435 flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
99 matthewc 432 if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
100     flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
101    
102     out_uint32_le(s, length);
103     out_uint32_le(s, flags);
104     data = s->end = s->p + thislength;
105 forsberg 473 DEBUG_CLIPBOARD(("Sending %d bytes with FLAG_FIRST\n", thislength));
106 jsorg71 437 sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
107 matthewc 432
108     /* subsequent segments copied (otherwise would have to generate headers backwards) */
109     while (remaining > 0)
110 forsberg 400 {
111 matthewc 432 thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
112     remaining -= thislength;
113     flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
114 forsberg 473 if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
115     flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
116 matthewc 432
117 forsberg 473 DEBUG_CLIPBOARD(("Sending %d bytes with flags %d\n", thislength, flags));
118    
119 jsorg71 437 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
120 matthewc 432 out_uint32_le(s, length);
121     out_uint32_le(s, flags);
122     out_uint8p(s, data, thislength);
123     s_mark_end(s);
124 jsorg71 437 sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
125 matthewc 432
126     data += thislength;
127 forsberg 400 }
128     }
129    
130 matthewc 432 void
131     channel_process(STREAM s, uint16 mcs_channel)
132 forsberg 400 {
133 matthewc 432 uint32 length, flags;
134     uint32 thislength;
135     VCHANNEL *channel;
136     unsigned int i;
137     STREAM in;
138    
139     for (i = 0; i < g_num_channels; i++)
140 forsberg 400 {
141 matthewc 432 channel = &g_channels[i];
142     if (channel->mcs_id == mcs_channel)
143     break;
144 forsberg 400 }
145 matthewc 432
146     if (i >= g_num_channels)
147     return;
148    
149     in_uint32_le(s, length);
150     in_uint32_le(s, flags);
151     if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
152     {
153     /* single fragment - pass straight up */
154     channel->process(s);
155     }
156 forsberg 400 else
157     {
158 matthewc 432 /* add fragment to defragmentation buffer */
159     in = &channel->in;
160     if (flags & CHANNEL_FLAG_FIRST)
161     {
162     if (length > in->size)
163     {
164     in->data = xrealloc(in->data, length);
165     in->size = length;
166     }
167     in->p = in->data;
168     }
169 forsberg 400
170 matthewc 446 thislength = MIN(s->end - s->p, in->data + in->size - in->p);
171 matthewc 432 memcpy(in->p, s->p, thislength);
172 matthewc 446 in->p += thislength;
173 forsberg 400
174 matthewc 432 if (flags & CHANNEL_FLAG_LAST)
175     {
176 matthewc 446 in->end = in->p;
177 matthewc 432 in->p = in->data;
178     channel->process(in);
179     }
180     }
181 forsberg 400 }

  ViewVC Help
Powered by ViewVC 1.1.26