/[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 1248 - (show annotations)
Wed Jul 12 12:01:56 2006 UTC (17 years, 9 months ago) by ossman_
File MIME type: text/plain
File size: 5755 byte(s)
Add some simple reference counting for vchannel_open()/close() as it might
be done multple times as seamlessrdp.dll hooks into seamlessrdpshell.exe.

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

  ViewVC Help
Powered by ViewVC 1.1.26