/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/vchannel.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

Annotation of /sourceforge.net/trunk/seamlessrdp/ServerExe/vchannel.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1163 - (hide annotations)
Mon Mar 20 10:31:58 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 5618 byte(s)
Add serial numbers to protocol.

1 ossman_ 1073 /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.
3     Seamless windows - Virtual channel handling
4    
5     Copyright (C) Pierre Ossman <ossman@cendio.se> 2006
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 2 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, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     */
21    
22     #include <assert.h>
23     #include <stdio.h>
24     #include <stdarg.h>
25 ossman_ 1074 #include <errno.h>
26 ossman_ 1073
27     #include <windows.h>
28     #include <wtsapi32.h>
29     #include <cchannel.h>
30    
31     #include "vchannel.h"
32    
33     #define CHANNELNAME "seamrdp"
34    
35 ossman_ 1113 #define INVALID_CHARS ","
36     #define REPLACEMENT_CHAR '_'
37    
38 ossman_ 1163 #ifdef __GNUC__
39     #define SHARED __attribute__((section ("SHAREDDATA"), shared))
40     #else
41     #define SHARED
42     #endif
43    
44     // Shared DATA
45     #pragma data_seg ( "SHAREDDATA" )
46    
47     unsigned int g_vchannel_serial SHARED = 0;
48    
49     #pragma data_seg ()
50    
51     #pragma comment(linker, "/section:SHAREDDATA,rws")
52    
53 ossman_ 1073 static HANDLE g_mutex = NULL;
54     static HANDLE g_vchannel = NULL;
55    
56 ossman_ 1163 DLL_EXPORT void
57 ossman_ 1073 debug(char *format, ...)
58     {
59     va_list argp;
60     char buf[256];
61    
62     va_start(argp, format);
63 ossman_ 1163 _vsnprintf(buf, sizeof(buf), format, argp);
64 ossman_ 1073 va_end(argp);
65    
66 ossman_ 1163 vchannel_strfilter(buf);
67 ossman_ 1113
68 ossman_ 1163 vchannel_write("DEBUG", buf);
69 ossman_ 1073 }
70    
71 ossman_ 1134 #define CONVERT_BUFFER_SIZE 1024
72     static char convert_buffer[CONVERT_BUFFER_SIZE];
73 ossman_ 1073
74 ossman_ 1163 DLL_EXPORT const char *
75 ossman_ 1134 unicode_to_utf8(const unsigned short *string)
76     {
77     unsigned char *buf;
78     size_t size;
79    
80     buf = (unsigned char *) convert_buffer;
81     size = sizeof(convert_buffer) - 1;
82    
83     /* We do not handle characters outside BMP (i.e. we can't do UTF-16) */
84     while (*string != 0x0000)
85     {
86     if (*string < 0x80)
87     {
88     if (size < 1)
89     break;
90     *buf++ = (unsigned char) *string;
91     size--;
92     }
93     else if (*string < 0x800)
94     {
95     if (size < 2)
96     break;
97     *buf++ = 0xC0 | (*string >> 6);
98     *buf++ = 0x80 | (*string & 0x3F);
99     size -= 2;
100     }
101 ossman_ 1152 else if ((*string < 0xD800) || (*string > 0xDFFF))
102 ossman_ 1134 {
103     if (size < 3)
104     break;
105     *buf++ = 0xE0 | (*string >> 12);
106     *buf++ = 0x80 | (*string >> 6 & 0x3F);
107     *buf++ = 0x80 | (*string & 0x3F);
108     size -= 2;
109     }
110    
111     string++;
112     }
113    
114     *buf = '\0';
115    
116     return convert_buffer;
117     }
118    
119 ossman_ 1163 DLL_EXPORT int
120 ossman_ 1073 vchannel_open()
121     {
122     g_vchannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE,
123     WTS_CURRENT_SESSION, CHANNELNAME);
124    
125     if (g_vchannel == NULL)
126     return -1;
127    
128     g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessChannel");
129 ossman_ 1078 if (!g_mutex)
130     {
131 ossman_ 1073 WTSVirtualChannelClose(g_vchannel);
132     g_vchannel = NULL;
133     return -1;
134     }
135    
136     return 0;
137     }
138    
139 ossman_ 1163 DLL_EXPORT void
140 ossman_ 1073 vchannel_close()
141     {
142     if (g_mutex)
143     CloseHandle(g_mutex);
144    
145     if (g_vchannel)
146     WTSVirtualChannelClose(g_vchannel);
147    
148     g_mutex = NULL;
149     g_vchannel = NULL;
150     }
151    
152 ossman_ 1163 DLL_EXPORT int
153 ossman_ 1073 vchannel_is_open()
154     {
155     if (g_vchannel == NULL)
156     return 0;
157     else
158     return 1;
159     }
160    
161 ossman_ 1163 DLL_EXPORT int
162 ossman_ 1074 vchannel_read(char *line, size_t length)
163 ossman_ 1073 {
164 ossman_ 1074 static BOOL overflow_mode = FALSE;
165     static char buffer[VCHANNEL_MAX_LINE];
166     static size_t size = 0;
167    
168     char *newline;
169     int line_size;
170    
171     BOOL result;
172     ULONG bytes_read;
173    
174     result = WTSVirtualChannelRead(g_vchannel, 0, buffer + size,
175     sizeof(buffer) - size, &bytes_read);
176    
177 ossman_ 1078 if (!result)
178     {
179 ossman_ 1074 errno = EIO;
180     return -1;
181     }
182    
183 ossman_ 1078 if (overflow_mode)
184     {
185 ossman_ 1074 newline = strchr(buffer, '\n');
186 ossman_ 1078 if (newline && (newline - buffer) < bytes_read)
187     {
188 ossman_ 1074 size = bytes_read - (newline - buffer) - 1;
189     memmove(buffer, newline + 1, size);
190     overflow_mode = FALSE;
191     }
192     }
193     else
194     size += bytes_read;
195    
196 ossman_ 1078 if (overflow_mode)
197     {
198 ossman_ 1074 errno = -EAGAIN;
199     return -1;
200     }
201    
202     newline = strchr(buffer, '\n');
203 ossman_ 1078 if (!newline || (newline - buffer) >= size)
204     {
205     if (size == sizeof(buffer))
206     {
207 ossman_ 1074 overflow_mode = TRUE;
208     size = 0;
209     }
210     errno = -EAGAIN;
211     return -1;
212     }
213    
214 ossman_ 1078 if ((newline - buffer) >= length)
215     {
216 ossman_ 1074 errno = ENOMEM;
217     return -1;
218     }
219    
220     *newline = '\0';
221    
222     strcpy(line, buffer);
223     line_size = newline - buffer;
224    
225     size -= newline - buffer + 1;
226     memmove(buffer, newline + 1, size);
227    
228     return 0;
229 ossman_ 1073 }
230    
231 ossman_ 1163 DLL_EXPORT int
232     vchannel_write(const char *command, const char *format, ...)
233 ossman_ 1073 {
234     BOOL result;
235     va_list argp;
236 ossman_ 1074 char buf[VCHANNEL_MAX_LINE];
237 ossman_ 1073 int size;
238     ULONG bytes_written;
239    
240     assert(vchannel_is_open());
241    
242 ossman_ 1163 WaitForSingleObject(g_mutex, INFINITE);
243    
244     size = _snprintf(buf, sizeof(buf), "%s,%u,", command, g_vchannel_serial);
245    
246     assert(size < sizeof(buf));
247    
248 ossman_ 1073 va_start(argp, format);
249 ossman_ 1163 size += _vsnprintf(buf + size, sizeof(buf) - size, format, argp);
250 ossman_ 1073 va_end(argp);
251    
252     assert(size < sizeof(buf));
253    
254     result = WTSVirtualChannelWrite(g_vchannel, buf, (ULONG) strlen(buf), &bytes_written);
255     result = WTSVirtualChannelWrite(g_vchannel, "\n", (ULONG) 1, &bytes_written);
256 ossman_ 1163
257     g_vchannel_serial++;
258    
259 ossman_ 1073 ReleaseMutex(g_mutex);
260    
261     if (!result)
262     return -1;
263    
264     return bytes_written;
265     }
266 ossman_ 1075
267 ossman_ 1163 DLL_EXPORT void
268 ossman_ 1075 vchannel_block()
269     {
270     WaitForSingleObject(g_mutex, INFINITE);
271     }
272    
273 ossman_ 1163 DLL_EXPORT void
274 ossman_ 1075 vchannel_unblock()
275     {
276     ReleaseMutex(g_mutex);
277     }
278 ossman_ 1113
279 ossman_ 1163 DLL_EXPORT const char *
280 ossman_ 1113 vchannel_strfilter(char *string)
281     {
282     char *c;
283    
284     for (c = string; *c != '\0'; c++)
285     {
286 ossman_ 1129 if (((unsigned char) *c < 0x20) || (strchr(INVALID_CHARS, *c) != NULL))
287 ossman_ 1113 *c = REPLACEMENT_CHAR;
288     }
289    
290     return string;
291     }
292 ossman_ 1134
293 ossman_ 1163 DLL_EXPORT const char *
294 ossman_ 1134 vchannel_strfilter_unicode(const unsigned short *string)
295     {
296     return vchannel_strfilter((char *) unicode_to_utf8(string));
297     }

  ViewVC Help
Powered by ViewVC 1.1.26