/[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

Diff of /sourceforge.net/trunk/rdesktop/channels.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 400 by forsberg, Fri Jun 6 10:10:19 2003 UTC revision 499 by astrand, Wed Oct 15 14:01:32 2003 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - Channel register     Protocol services - Virtual channels
4     Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003     Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
5       Copyright (C) Matthew Chapman 2003
6    
7     This program is free software; you can redistribute it and/or modify     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     it under the terms of the GNU General Public License as published by
# Line 20  Line 21 
21    
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24  static uint16 num_channels;  #define MAX_CHANNELS                    4
25  static rdp5_channel *channels[MAX_RDP5_CHANNELS];  #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    
30    extern BOOL g_use_rdp5;
31    extern BOOL g_encryption;
32    
33    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       channels to MCS channels.
38    
39       The format of TAG_SRV_CHANNELS seems to be
40    
41       global_channel_no (uint16le)
42       number_of_other_channels (uint16le)
43       ..followed by uint16les for the other channels.
44    */
45    
46  uint16  VCHANNEL *
47  get_num_channels(void)  channel_register(char *name, uint32 flags, void (*callback) (STREAM))
48  {  {
49          return num_channels;          VCHANNEL *channel;
50    
51            if (!g_use_rdp5)
52                    return NULL;
53    
54            if (g_num_channels >= MAX_CHANNELS)
55            {
56                    error("Channel table full, increase MAX_CHANNELS\n");
57                    return NULL;
58            }
59    
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    }
68    
69    STREAM
70    channel_init(VCHANNEL * channel, uint32 length)
71    {
72            STREAM s;
73    
74            s = sec_init(g_encryption ? SEC_ENCRYPT : 0, length + 8);
75            s_push_layer(s, channel_hdr, 8);
76            return s;
77  }  }
78    
79  void  void
80  register_channel(char *name, uint32 flags, void (*callback) (STREAM, uint16))  channel_send(STREAM s, VCHANNEL * channel)
81  {  {
82          if (num_channels > MAX_RDP5_CHANNELS)          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            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            remaining = length - thislength;
98            flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
99            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            DEBUG_CLIPBOARD(("Sending %d bytes with FLAG_FIRST\n", thislength));
106            sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
107    
108            /* subsequent segments copied (otherwise would have to generate headers backwards) */
109            while (remaining > 0)
110          {          {
111                  error("Maximum number of RDP5 channels reached. Redefine MAX_RDP5_CHANNELS in constants.h and recompile!\n!");                  thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
112                    remaining -= thislength;
113                    flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
114                    if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
115                            flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
116    
117                    DEBUG_CLIPBOARD(("Sending %d bytes with flags %d\n", thislength, flags));
118    
119                    s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
120                    out_uint32_le(s, length);
121                    out_uint32_le(s, flags);
122                    out_uint8p(s, data, thislength);
123                    s_mark_end(s);
124                    sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
125    
126                    data += thislength;
127          }          }
         num_channels++;  
         channels[num_channels - 1] = xrealloc(channels[num_channels - 1],  
                                               sizeof(rdp5_channel) * num_channels);  
         channels[num_channels - 1]->channelno = MCS_GLOBAL_CHANNEL + num_channels;  
         strcpy(channels[num_channels - 1]->name, name);  
         channels[num_channels - 1]->channelflags = flags;  
         channels[num_channels - 1]->channelcallback = callback;  
128  }  }
129    
130  rdp5_channel *  void
131  find_channel_by_channelno(uint16 channelno)  channel_process(STREAM s, uint16 mcs_channel)
132  {  {
133          if (channelno > MCS_GLOBAL_CHANNEL + num_channels)          uint32 length, flags;
134          {          uint32 thislength;
135                  warning("Channel %d not defined. Highest channel defined is %d\n",          VCHANNEL *channel;
136                          channelno, MCS_GLOBAL_CHANNEL + num_channels);          unsigned int i;
137                  return NULL;          STREAM in;
138          }  
139          else          for (i = 0; i < g_num_channels; i++)
140          {          {
141                  return channels[channelno - MCS_GLOBAL_CHANNEL - 1];                  channel = &g_channels[i];
142                    if (channel->mcs_id == mcs_channel)
143                            break;
144          }          }
 }  
145    
146  rdp5_channel *          if (i >= g_num_channels)
147  find_channel_by_num(uint16 num)                  return;
148  {  
149          if (num > num_channels)          in_uint32_le(s, length);
150            in_uint32_le(s, flags);
151            if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
152          {          {
153                  error("There are only %d channels defined, channel %d doesn't exist\n",                  /* single fragment - pass straight up */
154                        num_channels, num);                  channel->process(s);
155          }          }
156          else          else
157          {          {
158                  return channels[num];                  /* 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    
170                    thislength = MIN(s->end - s->p, in->data + in->size - in->p);
171                    memcpy(in->p, s->p, thislength);
172                    in->p += thislength;
173    
174                    if (flags & CHANNEL_FLAG_LAST)
175                    {
176                            in->end = in->p;
177                            in->p = in->data;
178                            channel->process(in);
179                    }
180          }          }
         return NULL;            // Shut the compiler up  
 }  
   
   
   
 void  
 dummy_callback(STREAM s, uint16 channelno)  
 {  
         warning("Server is sending information on our dummy channel (%d). Why?\n", channelno);  
 }  
   
 void  
 channels_init(void)  
 {  
         DEBUG_RDP5(("channels_init\n"));  
         register_channel("dummych", 0xc0a0, dummy_callback);  
         register_channel("cliprdr", 0xc0a0, cliprdr_callback);  
181  }  }

Legend:
Removed from v.400  
changed lines
  Added in v.499

  ViewVC Help
Powered by ViewVC 1.1.26