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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1152 - (show annotations)
Fri Mar 17 09:54:17 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 5137 byte(s)
Acidentally implemented the USC-4 algorithm instead of the USC-2 one.

1 /* -*- 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 #include <errno.h>
26
27 #include <windows.h>
28 #include <wtsapi32.h>
29 #include <cchannel.h>
30
31 #include "vchannel.h"
32
33 #define CHANNELNAME "seamrdp"
34
35 #define INVALID_CHARS ","
36 #define REPLACEMENT_CHAR '_'
37
38 static HANDLE g_mutex = NULL;
39 static HANDLE g_vchannel = NULL;
40
41 void
42 debug(char *format, ...)
43 {
44 va_list argp;
45 char buf[256];
46
47 sprintf(buf, "DEBUG,");
48
49 va_start(argp, format);
50 _vsnprintf(buf + sizeof("DEBUG,") - 1, sizeof(buf) - sizeof("DEBUG,") + 1, format, argp);
51 va_end(argp);
52
53 vchannel_strfilter(buf + sizeof("DEBUG,"));
54
55 vchannel_write(buf);
56 }
57
58 #define CONVERT_BUFFER_SIZE 1024
59 static char convert_buffer[CONVERT_BUFFER_SIZE];
60
61 const char *
62 unicode_to_utf8(const unsigned short *string)
63 {
64 unsigned char *buf;
65 size_t size;
66
67 buf = (unsigned char *) convert_buffer;
68 size = sizeof(convert_buffer) - 1;
69
70 /* We do not handle characters outside BMP (i.e. we can't do UTF-16) */
71 while (*string != 0x0000)
72 {
73 if (*string < 0x80)
74 {
75 if (size < 1)
76 break;
77 *buf++ = (unsigned char) *string;
78 size--;
79 }
80 else if (*string < 0x800)
81 {
82 if (size < 2)
83 break;
84 *buf++ = 0xC0 | (*string >> 6);
85 *buf++ = 0x80 | (*string & 0x3F);
86 size -= 2;
87 }
88 else if ((*string < 0xD800) || (*string > 0xDFFF))
89 {
90 if (size < 3)
91 break;
92 *buf++ = 0xE0 | (*string >> 12);
93 *buf++ = 0x80 | (*string >> 6 & 0x3F);
94 *buf++ = 0x80 | (*string & 0x3F);
95 size -= 2;
96 }
97
98 string++;
99 }
100
101 *buf = '\0';
102
103 return convert_buffer;
104 }
105
106 int
107 vchannel_open()
108 {
109 g_vchannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE,
110 WTS_CURRENT_SESSION, CHANNELNAME);
111
112 if (g_vchannel == NULL)
113 return -1;
114
115 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessChannel");
116 if (!g_mutex)
117 {
118 WTSVirtualChannelClose(g_vchannel);
119 g_vchannel = NULL;
120 return -1;
121 }
122
123 return 0;
124 }
125
126 void
127 vchannel_close()
128 {
129 if (g_mutex)
130 CloseHandle(g_mutex);
131
132 if (g_vchannel)
133 WTSVirtualChannelClose(g_vchannel);
134
135 g_mutex = NULL;
136 g_vchannel = NULL;
137 }
138
139 int
140 vchannel_is_open()
141 {
142 if (g_vchannel == NULL)
143 return 0;
144 else
145 return 1;
146 }
147
148 int
149 vchannel_read(char *line, size_t length)
150 {
151 static BOOL overflow_mode = FALSE;
152 static char buffer[VCHANNEL_MAX_LINE];
153 static size_t size = 0;
154
155 char *newline;
156 int line_size;
157
158 BOOL result;
159 ULONG bytes_read;
160
161 result = WTSVirtualChannelRead(g_vchannel, 0, buffer + size,
162 sizeof(buffer) - size, &bytes_read);
163
164 if (!result)
165 {
166 errno = EIO;
167 return -1;
168 }
169
170 if (overflow_mode)
171 {
172 newline = strchr(buffer, '\n');
173 if (newline && (newline - buffer) < bytes_read)
174 {
175 size = bytes_read - (newline - buffer) - 1;
176 memmove(buffer, newline + 1, size);
177 overflow_mode = FALSE;
178 }
179 }
180 else
181 size += bytes_read;
182
183 if (overflow_mode)
184 {
185 errno = -EAGAIN;
186 return -1;
187 }
188
189 newline = strchr(buffer, '\n');
190 if (!newline || (newline - buffer) >= size)
191 {
192 if (size == sizeof(buffer))
193 {
194 overflow_mode = TRUE;
195 size = 0;
196 }
197 errno = -EAGAIN;
198 return -1;
199 }
200
201 if ((newline - buffer) >= length)
202 {
203 errno = ENOMEM;
204 return -1;
205 }
206
207 *newline = '\0';
208
209 strcpy(line, buffer);
210 line_size = newline - buffer;
211
212 size -= newline - buffer + 1;
213 memmove(buffer, newline + 1, size);
214
215 return 0;
216 }
217
218 int
219 vchannel_write(const char *format, ...)
220 {
221 BOOL result;
222 va_list argp;
223 char buf[VCHANNEL_MAX_LINE];
224 int size;
225 ULONG bytes_written;
226
227 assert(vchannel_is_open());
228
229 va_start(argp, format);
230 size = _vsnprintf(buf, sizeof(buf), format, argp);
231 va_end(argp);
232
233 assert(size < sizeof(buf));
234
235 WaitForSingleObject(g_mutex, INFINITE);
236 result = WTSVirtualChannelWrite(g_vchannel, buf, (ULONG) strlen(buf), &bytes_written);
237 result = WTSVirtualChannelWrite(g_vchannel, "\n", (ULONG) 1, &bytes_written);
238 ReleaseMutex(g_mutex);
239
240 if (!result)
241 return -1;
242
243 return bytes_written;
244 }
245
246 void
247 vchannel_block()
248 {
249 WaitForSingleObject(g_mutex, INFINITE);
250 }
251
252 void
253 vchannel_unblock()
254 {
255 ReleaseMutex(g_mutex);
256 }
257
258 const char *
259 vchannel_strfilter(char *string)
260 {
261 char *c;
262
263 for (c = string; *c != '\0'; c++)
264 {
265 if (((unsigned char) *c < 0x20) || (strchr(INVALID_CHARS, *c) != NULL))
266 *c = REPLACEMENT_CHAR;
267 }
268
269 return string;
270 }
271
272 const char *
273 vchannel_strfilter_unicode(const unsigned short *string)
274 {
275 return vchannel_strfilter((char *) unicode_to_utf8(string));
276 }

  ViewVC Help
Powered by ViewVC 1.1.26