/[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 1129 - (show annotations)
Wed Mar 15 12:08:32 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 4107 byte(s)
Let characters outside the ascii range through.

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
59 int
60 vchannel_open()
61 {
62 g_vchannel = WTSVirtualChannelOpen(WTS_CURRENT_SERVER_HANDLE,
63 WTS_CURRENT_SESSION, CHANNELNAME);
64
65 if (g_vchannel == NULL)
66 return -1;
67
68 g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessChannel");
69 if (!g_mutex)
70 {
71 WTSVirtualChannelClose(g_vchannel);
72 g_vchannel = NULL;
73 return -1;
74 }
75
76 return 0;
77 }
78
79 void
80 vchannel_close()
81 {
82 if (g_mutex)
83 CloseHandle(g_mutex);
84
85 if (g_vchannel)
86 WTSVirtualChannelClose(g_vchannel);
87
88 g_mutex = NULL;
89 g_vchannel = NULL;
90 }
91
92 int
93 vchannel_is_open()
94 {
95 if (g_vchannel == NULL)
96 return 0;
97 else
98 return 1;
99 }
100
101 int
102 vchannel_read(char *line, size_t length)
103 {
104 static BOOL overflow_mode = FALSE;
105 static char buffer[VCHANNEL_MAX_LINE];
106 static size_t size = 0;
107
108 char *newline;
109 int line_size;
110
111 BOOL result;
112 ULONG bytes_read;
113
114 result = WTSVirtualChannelRead(g_vchannel, 0, buffer + size,
115 sizeof(buffer) - size, &bytes_read);
116
117 if (!result)
118 {
119 errno = EIO;
120 return -1;
121 }
122
123 if (overflow_mode)
124 {
125 newline = strchr(buffer, '\n');
126 if (newline && (newline - buffer) < bytes_read)
127 {
128 size = bytes_read - (newline - buffer) - 1;
129 memmove(buffer, newline + 1, size);
130 overflow_mode = FALSE;
131 }
132 }
133 else
134 size += bytes_read;
135
136 if (overflow_mode)
137 {
138 errno = -EAGAIN;
139 return -1;
140 }
141
142 newline = strchr(buffer, '\n');
143 if (!newline || (newline - buffer) >= size)
144 {
145 if (size == sizeof(buffer))
146 {
147 overflow_mode = TRUE;
148 size = 0;
149 }
150 errno = -EAGAIN;
151 return -1;
152 }
153
154 if ((newline - buffer) >= length)
155 {
156 errno = ENOMEM;
157 return -1;
158 }
159
160 *newline = '\0';
161
162 strcpy(line, buffer);
163 line_size = newline - buffer;
164
165 size -= newline - buffer + 1;
166 memmove(buffer, newline + 1, size);
167
168 return 0;
169 }
170
171 int
172 vchannel_write(const char *format, ...)
173 {
174 BOOL result;
175 va_list argp;
176 char buf[VCHANNEL_MAX_LINE];
177 int size;
178 ULONG bytes_written;
179
180 assert(vchannel_is_open());
181
182 va_start(argp, format);
183 size = _vsnprintf(buf, sizeof(buf), format, argp);
184 va_end(argp);
185
186 assert(size < sizeof(buf));
187
188 WaitForSingleObject(g_mutex, INFINITE);
189 result = WTSVirtualChannelWrite(g_vchannel, buf, (ULONG) strlen(buf), &bytes_written);
190 result = WTSVirtualChannelWrite(g_vchannel, "\n", (ULONG) 1, &bytes_written);
191 ReleaseMutex(g_mutex);
192
193 if (!result)
194 return -1;
195
196 return bytes_written;
197 }
198
199 void
200 vchannel_block()
201 {
202 WaitForSingleObject(g_mutex, INFINITE);
203 }
204
205 void
206 vchannel_unblock()
207 {
208 ReleaseMutex(g_mutex);
209 }
210
211 const char *
212 vchannel_strfilter(char *string)
213 {
214 char *c;
215
216 for (c = string; *c != '\0'; c++)
217 {
218 if (((unsigned char) *c < 0x20) || (strchr(INVALID_CHARS, *c) != NULL))
219 *c = REPLACEMENT_CHAR;
220 }
221
222 return string;
223 }

  ViewVC Help
Powered by ViewVC 1.1.26