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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1475 - (hide annotations)
Fri Jul 11 03:51:23 2008 UTC (15 years, 10 months ago) by jsorg71
File MIME type: text/plain
File size: 4969 byte(s)
update the copyright year

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 jsorg71 1475 Copyright (C) Matthew Chapman 2003-2008
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 astrand 1199 #define MAX_CHANNELS 6
25 matthewc 432 #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 1372 extern RD_BOOL g_use_rdp5;
31     extern RD_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 matthewc 536 uint8 *data;
85 matthewc 432
86 stargo 1328 #ifdef WITH_SCARD
87     scard_lock(SCARD_LOCK_CHANNEL);
88     #endif
89    
90 matthewc 432 /* first fragment sent in-place */
91     s_pop_layer(s, channel_hdr);
92     length = s->end - s->p - 8;
93    
94 astrand 1199 DEBUG_CHANNEL(("channel_send, length = %d\n", length));
95 forsberg 473
96 astrand 499 thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
97 forsberg 473 /* Note: In the original clipboard implementation, this number was
98     1592, not 1600. However, I don't remember the reason and 1600 seems
99     to work so.. This applies only to *this* length, not the length of
100     continuation or ending packets. */
101 matthewc 432 remaining = length - thislength;
102 astrand 435 flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
103 matthewc 432 if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
104     flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
105    
106     out_uint32_le(s, length);
107     out_uint32_le(s, flags);
108     data = s->end = s->p + thislength;
109 astrand 1199 DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength));
110 jsorg71 437 sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
111 matthewc 432
112     /* subsequent segments copied (otherwise would have to generate headers backwards) */
113     while (remaining > 0)
114 forsberg 400 {
115 matthewc 432 thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
116     remaining -= thislength;
117     flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
118 forsberg 473 if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
119     flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
120 matthewc 432
121 astrand 1199 DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags));
122 forsberg 473
123 jsorg71 437 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
124 matthewc 432 out_uint32_le(s, length);
125     out_uint32_le(s, flags);
126     out_uint8p(s, data, thislength);
127     s_mark_end(s);
128 jsorg71 437 sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
129 matthewc 432
130     data += thislength;
131 forsberg 400 }
132 stargo 1328
133     #ifdef WITH_SCARD
134     scard_unlock(SCARD_LOCK_CHANNEL);
135     #endif
136 forsberg 400 }
137    
138 matthewc 432 void
139     channel_process(STREAM s, uint16 mcs_channel)
140 forsberg 400 {
141 matthewc 432 uint32 length, flags;
142     uint32 thislength;
143 stargo 506 VCHANNEL *channel = NULL;
144 matthewc 432 unsigned int i;
145     STREAM in;
146    
147     for (i = 0; i < g_num_channels; i++)
148 forsberg 400 {
149 matthewc 432 channel = &g_channels[i];
150     if (channel->mcs_id == mcs_channel)
151     break;
152 forsberg 400 }
153 matthewc 432
154     if (i >= g_num_channels)
155     return;
156    
157     in_uint32_le(s, length);
158     in_uint32_le(s, flags);
159     if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
160     {
161     /* single fragment - pass straight up */
162     channel->process(s);
163     }
164 forsberg 400 else
165     {
166 matthewc 432 /* add fragment to defragmentation buffer */
167     in = &channel->in;
168     if (flags & CHANNEL_FLAG_FIRST)
169     {
170     if (length > in->size)
171     {
172 astrand 717 in->data = (uint8 *) xrealloc(in->data, length);
173 matthewc 432 in->size = length;
174     }
175     in->p = in->data;
176     }
177 forsberg 400
178 matthewc 446 thislength = MIN(s->end - s->p, in->data + in->size - in->p);
179 matthewc 432 memcpy(in->p, s->p, thislength);
180 matthewc 446 in->p += thislength;
181 forsberg 400
182 matthewc 432 if (flags & CHANNEL_FLAG_LAST)
183     {
184 matthewc 446 in->end = in->p;
185 matthewc 432 in->p = in->data;
186     channel->process(in);
187     }
188     }
189 forsberg 400 }

  ViewVC Help
Powered by ViewVC 1.1.26