VirtualBox

source: vbox/trunk/src/VBox/RDP/client/channels.c@ 28587

Last change on this file since 28587 was 11982, checked in by vboxsync, 16 years ago

All: license header changes for 2.0 (OSE headers, add Sun GPL/LGPL disclaimer)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.3 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - Virtual channels
4 Copyright (C) Erik Forsberg <[email protected]> 2003
5 Copyright (C) Matthew Chapman 2003-2007
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
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/*
23 * Sun GPL Disclaimer: For the avoidance of doubt, except that if any license choice
24 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
25 * the General Public License version 2 (GPLv2) at this time for any software where
26 * a choice of GPL license versions is made available with the language indicating
27 * that GPLv2 or any later version may be used, or where a choice of which version
28 * of the GPL is applied is otherwise unspecified.
29 */
30
31#include "rdesktop.h"
32
33#define MAX_CHANNELS 6
34#define CHANNEL_CHUNK_LENGTH 1600
35#define CHANNEL_FLAG_FIRST 0x01
36#define CHANNEL_FLAG_LAST 0x02
37#define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
38
39extern RD_BOOL g_use_rdp5;
40extern RD_BOOL g_encryption;
41
42VCHANNEL g_channels[MAX_CHANNELS];
43unsigned int g_num_channels;
44
45/* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5
46 channels to MCS channels.
47
48 The format of TAG_SRV_CHANNELS seems to be
49
50 global_channel_no (uint16le)
51 number_of_other_channels (uint16le)
52 ..followed by uint16les for the other channels.
53*/
54
55VCHANNEL *
56channel_register(char *name, uint32 flags, void (*callback) (STREAM))
57{
58 VCHANNEL *channel;
59
60 if (!g_use_rdp5)
61 return NULL;
62
63 if (g_num_channels >= MAX_CHANNELS)
64 {
65 error("Channel table full, increase MAX_CHANNELS\n");
66 return NULL;
67 }
68
69 channel = &g_channels[g_num_channels];
70 channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
71 strncpy(channel->name, name, 8);
72 channel->flags = flags;
73 channel->process = callback;
74 g_num_channels++;
75 return channel;
76}
77
78STREAM
79channel_init(VCHANNEL * channel, uint32 length)
80{
81 STREAM s;
82
83 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
84 s_push_layer(s, channel_hdr, 8);
85 return s;
86}
87
88void
89channel_send(STREAM s, VCHANNEL * channel)
90{
91 uint32 length, flags;
92 uint32 thislength, remaining;
93 uint8 *data;
94
95#ifdef WITH_SCARD
96 scard_lock(SCARD_LOCK_CHANNEL);
97#endif
98
99 /* first fragment sent in-place */
100 s_pop_layer(s, channel_hdr);
101 length = s->end - s->p - 8;
102
103 DEBUG_CHANNEL(("channel_send, length = %d\n", length));
104
105 thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
106/* Note: In the original clipboard implementation, this number was
107 1592, not 1600. However, I don't remember the reason and 1600 seems
108 to work so.. This applies only to *this* length, not the length of
109 continuation or ending packets. */
110 remaining = length - thislength;
111 flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
112 if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
113 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
114
115 out_uint32_le(s, length);
116 out_uint32_le(s, flags);
117 data = s->end = s->p + thislength;
118 DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength));
119 sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
120
121 /* subsequent segments copied (otherwise would have to generate headers backwards) */
122 while (remaining > 0)
123 {
124 thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
125 remaining -= thislength;
126 flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
127 if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
128 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
129
130 DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags));
131
132 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
133 out_uint32_le(s, length);
134 out_uint32_le(s, flags);
135 out_uint8p(s, data, thislength);
136 s_mark_end(s);
137 sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
138
139 data += thislength;
140 }
141
142#ifdef WITH_SCARD
143 scard_unlock(SCARD_LOCK_CHANNEL);
144#endif
145}
146
147void
148channel_process(STREAM s, uint16 mcs_channel)
149{
150 uint32 length, flags;
151 uint32 thislength;
152 VCHANNEL *channel = NULL;
153 unsigned int i;
154 STREAM in;
155
156 for (i = 0; i < g_num_channels; i++)
157 {
158 channel = &g_channels[i];
159 if (channel->mcs_id == mcs_channel)
160 break;
161 }
162
163 if (i >= g_num_channels)
164 return;
165
166 in_uint32_le(s, length);
167 in_uint32_le(s, flags);
168 if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
169 {
170 /* single fragment - pass straight up */
171 channel->process(s);
172 }
173 else
174 {
175 /* add fragment to defragmentation buffer */
176 in = &channel->in;
177 if (flags & CHANNEL_FLAG_FIRST)
178 {
179 if (length > in->size)
180 {
181 in->data = (uint8 *) xrealloc(in->data, length);
182 in->size = length;
183 }
184 in->p = in->data;
185 }
186
187 thislength = MIN(s->end - s->p, in->data + in->size - in->p);
188 memcpy(in->p, s->p, thislength);
189 in->p += thislength;
190
191 if (flags & CHANNEL_FLAG_LAST)
192 {
193 in->end = in->p;
194 in->p = in->data;
195 channel->process(in);
196 }
197 }
198}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette