VirtualBox

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

Last change on this file since 37224 was 37224, checked in by vboxsync, 13 years ago

RDP/client: fix OSE

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