/[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 437 by jsorg71, Mon Jul 28 21:41:12 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 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 (!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            thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
91            remaining = length - thislength;
92            flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
93            if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
94                    flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
95    
96            out_uint32_le(s, length);
97            out_uint32_le(s, flags);
98            data = s->end = s->p + thislength;
99            sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
100    
101            /* subsequent segments copied (otherwise would have to generate headers backwards) */
102            while (remaining > 0)
103          {          {
104                  error("Maximum number of RDP5 channels reached. Redefine MAX_RDP5_CHANNELS in constants.h and recompile!\n!");                  thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
105                    remaining -= thislength;
106                    flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
107    
108                    s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
109                    out_uint32_le(s, length);
110                    out_uint32_le(s, flags);
111                    out_uint8p(s, data, thislength);
112                    s_mark_end(s);
113                    sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
114    
115                    data += thislength;
116          }          }
         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;  
117  }  }
118    
119  rdp5_channel *  void
120  find_channel_by_channelno(uint16 channelno)  channel_process(STREAM s, uint16 mcs_channel)
121  {  {
122          if (channelno > MCS_GLOBAL_CHANNEL + num_channels)          uint32 length, flags;
123          {          uint32 thislength;
124                  warning("Channel %d not defined. Highest channel defined is %d\n",          VCHANNEL *channel;
125                          channelno, MCS_GLOBAL_CHANNEL + num_channels);          unsigned int i;
126                  return NULL;          STREAM in;
127          }  
128          else          for (i = 0; i < g_num_channels; i++)
129          {          {
130                  return channels[channelno - MCS_GLOBAL_CHANNEL - 1];                  channel = &g_channels[i];
131                    if (channel->mcs_id == mcs_channel)
132                            break;
133          }          }
 }  
134    
135  rdp5_channel *          if (i >= g_num_channels)
136  find_channel_by_num(uint16 num)                  return;
137  {  
138          if (num > num_channels)          in_uint32_le(s, length);
139            in_uint32_le(s, flags);
140            if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
141          {          {
142                  error("There are only %d channels defined, channel %d doesn't exist\n",                  /* single fragment - pass straight up */
143                        num_channels, num);                  channel->process(s);
144          }          }
145          else          else
146          {          {
147                  return channels[num];                  /* add fragment to defragmentation buffer */
148                    in = &channel->in;
149                    if (flags & CHANNEL_FLAG_FIRST)
150                    {
151                            if (length > in->size)
152                            {
153                                    in->data = xrealloc(in->data, length);
154                                    in->size = length;
155                            }
156                            in->p = in->data;
157                    }
158    
159                    thislength = s->end - s->p;
160                    memcpy(in->p, s->p, thislength);
161                    s->p += thislength;
162                    s->end += thislength;
163    
164                    if (flags & CHANNEL_FLAG_LAST)
165                    {
166                            in->p = in->data;
167                            channel->process(in);
168                    }
169          }          }
         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);  
170  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26