ReactOS  0.4.12-dev-51-ge94618b
channels.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  Protocol services - Virtual channels
4  Copyright 2003 Erik Forsberg <forsberg@cendio.se> for Cendio AB
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 #include "precomp.h"
22 
23 #define MAX_CHANNELS 6
24 #define CHANNEL_CHUNK_LENGTH 1600
25 #define CHANNEL_FLAG_FIRST 0x01
26 #define CHANNEL_FLAG_LAST 0x02
27 #define CHANNEL_FLAG_SHOW_PROTOCOL 0x10
28 
30 extern RD_BOOL g_encryption;
31 
33 unsigned int g_num_channels;
34 
35 /* FIXME: We should use the information in TAG_SRV_CHANNELS to map RDP5
36  channels to MCS channels.
37 
38  The format of TAG_SRV_CHANNELS seems to be
39 
40  global_channel_no (uint16le)
41  number_of_other_channels (uint16le)
42  ..followed by uint16les for the other channels.
43 */
44 
45 VCHANNEL *
47 {
48  VCHANNEL *channel;
49 
50  if (g_rdp_version < RDP_V5)
51  return NULL;
52 
54  {
55  error("Channel table full, increase MAX_CHANNELS\n");
56  return NULL;
57  }
58 
59  channel = &g_channels[g_num_channels];
60  channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
61  strncpy(channel->name, name, 8);
62  channel->flags = flags;
63  channel->process = callback;
64  g_num_channels++;
65  return channel;
66 }
67 
68 STREAM
70 {
71  STREAM s;
72 
73  s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
74  s_push_layer(s, channel_hdr, 8);
75  return s;
76 }
77 
78 void
80 {
82  uint32 thislength, remaining;
83  uint8 *data;
84 
85 #ifdef WITH_SCARD
87 #endif
88 
89  /* first fragment sent in-place */
90  s_pop_layer(s, channel_hdr);
91  length = s->end - s->p - 8;
92 
93  DEBUG_CHANNEL(("channel_send, length = %d\n", length));
94 
95  thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
96 /* Note: In the original clipboard implementation, this number was
97  1592, not 1600. However, I don't remember the reason and 1600 seems
98  to work so.. This applies only to *this* length, not the length of
99  continuation or ending packets. */
100  remaining = length - thislength;
101  flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
102  if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
104 
105  out_uint32_le(s, length);
106  out_uint32_le(s, flags);
107  data = s->end = s->p + thislength;
108  DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength));
110 
111  /* subsequent segments copied (otherwise would have to generate headers backwards) */
112  while (remaining > 0)
113  {
114  thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
115  remaining -= thislength;
116  flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
117  if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
119 
120  DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags));
121 
122  s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
123  out_uint32_le(s, length);
124  out_uint32_le(s, flags);
125  out_uint8p(s, data, thislength);
126  s_mark_end(s);
127  sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
128 
129  data += thislength;
130  }
131 
132 #ifdef WITH_SCARD
134 #endif
135 }
136 
137 void
139 {
141  uint32 thislength;
142  VCHANNEL *channel = NULL;
143  unsigned int i;
144  STREAM in;
145 
146  for (i = 0; i < g_num_channels; i++)
147  {
148  channel = &g_channels[i];
149  if (channel->mcs_id == mcs_channel)
150  break;
151  }
152 
153  if (i >= g_num_channels)
154  return;
155 
156  in_uint32_le(s, length);
157  in_uint32_le(s, flags);
158  if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
159  {
160  /* single fragment - pass straight up */
161  channel->process(s);
162  }
163  else
164  {
165  /* add fragment to defragmentation buffer */
166  in = &channel->in;
167  if (flags & CHANNEL_FLAG_FIRST)
168  {
169  if (length > in->size)
170  {
171  in->data = (uint8 *) xrealloc(in->data, length);
172  in->size = length;
173  }
174  in->p = in->data;
175  }
176 
177  thislength = MIN(s->end - s->p, in->data + in->size - in->p);
178  memcpy(in->p, s->p, thislength);
179  in->p += thislength;
180 
181  if (flags & CHANNEL_FLAG_LAST)
182  {
183  in->end = in->p;
184  in->p = in->data;
185  channel->process(in);
186  }
187  }
188 }
#define out_uint8p(s, v, n)
Definition: parse.h:93
struct stream in
Definition: types.h:155
#define error(str)
Definition: mkdosfs.c:1605
unsigned int uint32
Definition: types.h:32
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
STREAM sec_init(uint32 flags, int maxlen)
Definition: secure.c:419
#define CHANNEL_CHUNK_LENGTH
Definition: channels.c:24
#define out_uint32_le(s, v)
Definition: parse.h:59
RD_BOOL g_encryption
Definition: uimain.c:40
char name[8]
Definition: types.h:153
void channel_process(STREAM s, uint16 mcs_channel)
Definition: channels.c:138
#define CHANNEL_FLAG_LAST
Definition: channels.c:26
unsigned char * data
Definition: parse.h:26
#define SCARD_LOCK_CHANNEL
Definition: constants.h:581
#define MAX_CHANNELS
Definition: channels.c:23
T MIN(T a, T b)
Definition: polytest.cpp:79
#define MCS_GLOBAL_CHANNEL
Definition: constants.h:87
VCHANNEL * channel_register(char *name, uint32 flags, void(*callback)(STREAM))
Definition: channels.c:46
GLenum GLclampf GLint i
Definition: glfuncs.h:14
void * xrealloc(void *oldmem, size_t size)
Definition: uimain.c:736
#define CHANNEL_FLAG_FIRST
Definition: channels.c:25
#define s_pop_layer(s, h)
Definition: parse.h:40
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
RDP_VERSION g_rdp_version
Definition: uimain.c:74
smooth NULL
Definition: ftsmooth.c:416
uint32 flags
Definition: types.h:154
#define SEC_ENCRYPT
Definition: constants.h:101
int RD_BOOL
Definition: types.h:21
uint16 mcs_id
Definition: types.h:152
MmuTrapHandler callback[0x30]
Definition: mmuobject.c:44
Definition: types.h:44
void(* process)(STREAM)
Definition: types.h:156
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned char * end
Definition: parse.h:25
void scard_unlock(int lock)
unsigned char uint8
Definition: types.h:28
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLbitfield flags
Definition: glext.h:7161
unsigned int size
Definition: parse.h:27
Definition: parse.h:22
#define CHANNEL_FLAG_SHOW_PROTOCOL
Definition: channels.c:27
enum _RDP_VERSION RDP_VERSION
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLdouble s
Definition: gl.h:2039
VCHANNEL g_channels[MAX_CHANNELS]
Definition: channels.c:32
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel)
Definition: secure.c:436
#define s_push_layer(s, h, n)
Definition: parse.h:39
void scard_lock(int lock)
unsigned int g_num_channels
Definition: channels.c:33
unsigned short uint16
Definition: types.h:30
unsigned char * p
Definition: parse.h:24
Definition: name.c:36
#define s_mark_end(s)
Definition: parse.h:41
#define in_uint32_le(s, v)
Definition: parse.h:56
void channel_send(STREAM s, VCHANNEL *channel)
Definition: channels.c:79
STREAM channel_init(VCHANNEL *channel, uint32 length)
Definition: channels.c:69
#define CHANNEL_OPTION_SHOW_PROTOCOL
Definition: constants.h:434