/[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 419 by forsberg, Wed Jun 11 07:12:18 2003 UTC revision 432 by matthewc, Tue Jul 1 09:31:25 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  uint16  extern BOOL use_rdp5;
31  get_num_channels(void)  extern BOOL encryption;
 {  
         return num_channels;  
 }  
32    
33  /* FIXME: We should use the information in TAG_SRV_SRV_3 to map RDP5  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.     channels to MCS channels.
38    
39     The format of TAG_SRV_SRV_3 seems to be     The format of TAG_SRV_CHANNELS seems to be
40    
41     global_channel_no (uint16le)     global_channel_no (uint16le)
42     number_of_other_channels (uint16le)     number_of_other_channels (uint16le)
43     ..followed by uint16les for the other channels.     ..followed by uint16les for the other channels.
    Might be a few (two) bytes of padding at the end.  
   
44  */  */
45    
46  void  VCHANNEL *
47  register_channel(char *name, uint32 flags, void (*callback) (STREAM, uint16))  channel_register(char *name, uint32 flags, void (*callback) (STREAM))
48  {  {
49          if (num_channels > MAX_RDP5_CHANNELS)          VCHANNEL *channel;
50    
51            if (!use_rdp5)
52                    return NULL;
53    
54            if (g_num_channels >= MAX_CHANNELS)
55          {          {
56                  error("Maximum number of RDP5 channels reached. Redefine MAX_RDP5_CHANNELS in constants.h and recompile!\n!");                  error("Channel table full, increase MAX_CHANNELS\n");
57                    return NULL;
58          }          }
59          num_channels++;  
60          channels[num_channels - 1] = xrealloc(channels[num_channels - 1],          channel = &g_channels[g_num_channels];
61                                                sizeof(rdp5_channel) * num_channels);          channel->mcs_id = MCS_GLOBAL_CHANNEL + 1 + g_num_channels;
62          channels[num_channels - 1]->channelno = MCS_GLOBAL_CHANNEL + num_channels;          strncpy(channel->name, name, 8);
63          strcpy(channels[num_channels - 1]->name, name);          channel->flags = flags;
64          channels[num_channels - 1]->channelflags = flags;          channel->process = callback;
65          channels[num_channels - 1]->channelcallback = callback;          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(encryption ? SEC_ENCRYPT : 0, length + 8);
75            s_push_layer(s, channel_hdr, 8);
76            return s;
77  }  }
78    
79  rdp5_channel *  void
80  find_channel_by_channelno(uint16 channelno)  channel_send(STREAM s, VCHANNEL *channel)
81  {  {
82          if (channelno > MCS_GLOBAL_CHANNEL + num_channels)          uint32 length, flags;
83          {          uint32 thislength, remaining;
84                  warning("Channel %d not defined. Highest channel defined is %d\n",          char *data;
85                          channelno, MCS_GLOBAL_CHANNEL + num_channels);  
86                  return NULL;          /* first fragment sent in-place */
87          }          s_pop_layer(s, channel_hdr);
88          else          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, 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                  return channels[channelno - MCS_GLOBAL_CHANNEL - 1];                  thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
105                    remaining -= thislength;
106                    flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
107    
108                    s = sec_init(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, encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
114    
115                    data += thislength;
116          }          }
117  }  }
118    
119  rdp5_channel *  void
120  find_channel_by_num(uint16 num)  channel_process(STREAM s, uint16 mcs_channel)
121  {  {
122          if (num > num_channels)          uint32 length, flags;
123            uint32 thislength;
124            VCHANNEL *channel;
125            unsigned int i;
126            STREAM in;
127    
128            for (i = 0; i < g_num_channels; i++)
129            {
130                    channel = &g_channels[i];
131                    if (channel->mcs_id == mcs_channel)
132                            break;
133            }
134    
135            if (i >= g_num_channels)
136                    return;
137    
138            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);  
170  }  }
171    
 void  
 channels_init(void)  
 {  
         DEBUG_RDP5(("channels_init\n"));  
         register_channel("dummych", 0xc0a0, dummy_callback);  
         register_channel("cliprdr", 0xc0a0, cliprdr_callback);  
 }  

Legend:
Removed from v.419  
changed lines
  Added in v.432

  ViewVC Help
Powered by ViewVC 1.1.26