/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/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 1372 by jsorg71, Mon Jan 8 04:47:06 2007 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-2007
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                    6
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 RD_BOOL g_use_rdp5;
31    extern RD_BOOL g_encryption;
32    
33  uint16  VCHANNEL g_channels[MAX_CHANNELS];
34  get_num_channels(void)  unsigned int g_num_channels;
 {  
         return num_channels;  
 }  
35    
36  /* FIXME: We should use the information in TAG_SRV_SRV_3 to map RDP5  /* 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 (!g_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(g_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",          uint8 *data;
85                          channelno, MCS_GLOBAL_CHANNEL + num_channels);  
86                  return NULL;  #ifdef WITH_SCARD
87          }          scard_lock(SCARD_LOCK_CHANNEL);
88          else  #endif
89    
90            /* first fragment sent in-place */
91            s_pop_layer(s, channel_hdr);
92            length = s->end - s->p - 8;
93    
94            DEBUG_CHANNEL(("channel_send, length = %d\n", length));
95    
96            thislength = MIN(length, CHANNEL_CHUNK_LENGTH);
97    /* Note: In the original clipboard implementation, this number was
98       1592, not 1600. However, I don't remember the reason and 1600 seems
99       to work so.. This applies only to *this* length, not the length of
100       continuation or ending packets. */
101            remaining = length - thislength;
102            flags = (remaining == 0) ? CHANNEL_FLAG_FIRST | CHANNEL_FLAG_LAST : CHANNEL_FLAG_FIRST;
103            if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
104                    flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
105    
106            out_uint32_le(s, length);
107            out_uint32_le(s, flags);
108            data = s->end = s->p + thislength;
109            DEBUG_CHANNEL(("Sending %d bytes with FLAG_FIRST\n", thislength));
110            sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
111    
112            /* subsequent segments copied (otherwise would have to generate headers backwards) */
113            while (remaining > 0)
114          {          {
115                  return channels[channelno - MCS_GLOBAL_CHANNEL - 1];                  thislength = MIN(remaining, CHANNEL_CHUNK_LENGTH);
116                    remaining -= thislength;
117                    flags = (remaining == 0) ? CHANNEL_FLAG_LAST : 0;
118                    if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL)
119                            flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
120    
121                    DEBUG_CHANNEL(("Sending %d bytes with flags %d\n", thislength, flags));
122    
123                    s = sec_init(g_encryption ? SEC_ENCRYPT : 0, thislength + 8);
124                    out_uint32_le(s, length);
125                    out_uint32_le(s, flags);
126                    out_uint8p(s, data, thislength);
127                    s_mark_end(s);
128                    sec_send_to_channel(s, g_encryption ? SEC_ENCRYPT : 0, channel->mcs_id);
129    
130                    data += thislength;
131          }          }
132    
133    #ifdef WITH_SCARD
134            scard_unlock(SCARD_LOCK_CHANNEL);
135    #endif
136  }  }
137    
138  rdp5_channel *  void
139  find_channel_by_num(uint16 num)  channel_process(STREAM s, uint16 mcs_channel)
140  {  {
141          if (num > num_channels)          uint32 length, flags;
142            uint32 thislength;
143            VCHANNEL *channel = NULL;
144            unsigned int i;
145            STREAM in;
146    
147            for (i = 0; i < g_num_channels; i++)
148            {
149                    channel = &g_channels[i];
150                    if (channel->mcs_id == mcs_channel)
151                            break;
152            }
153    
154            if (i >= g_num_channels)
155                    return;
156    
157            in_uint32_le(s, length);
158            in_uint32_le(s, flags);
159            if ((flags & CHANNEL_FLAG_FIRST) && (flags & CHANNEL_FLAG_LAST))
160          {          {
161                  error("There are only %d channels defined, channel %d doesn't exist\n",                  /* single fragment - pass straight up */
162                        num_channels, num);                  channel->process(s);
163          }          }
164          else          else
165          {          {
166                  return channels[num];                  /* add fragment to defragmentation buffer */
167                    in = &channel->in;
168                    if (flags & CHANNEL_FLAG_FIRST)
169                    {
170                            if (length > in->size)
171                            {
172                                    in->data = (uint8 *) xrealloc(in->data, length);
173                                    in->size = length;
174                            }
175                            in->p = in->data;
176                    }
177    
178                    thislength = MIN(s->end - s->p, in->data + in->size - in->p);
179                    memcpy(in->p, s->p, thislength);
180                    in->p += thislength;
181    
182                    if (flags & CHANNEL_FLAG_LAST)
183                    {
184                            in->end = in->p;
185                            in->p = in->data;
186                            channel->process(in);
187                    }
188          }          }
         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);  
189  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26