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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1112 - (show annotations)
Fri Mar 10 16:14:37 2006 UTC (18 years, 1 month ago) by ossman_
File MIME type: text/plain
File size: 6474 byte(s)
Support client invoked POSITION and ZCHANGE.

1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Seamless windows - Remote server executable
4
5 Based on code copyright (C) 2004-2005 Martin Wickett
6
7 Copyright (C) Peter Åstrand <astrand@cendio.se> 2005-2006
8 Copyright (C) Pierre Ossman <ossman@cendio.se> 2006
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include <windows.h>
26 #include <stdio.h>
27
28 #include "vchannel.h"
29
30 #include "resource.h"
31
32 #define APP_NAME "SeamlessRDP Shell"
33
34 /* Global data */
35 static HINSTANCE g_instance;
36
37 typedef void (*set_hooks_proc_t) ();
38 typedef void (*remove_hooks_proc_t) ();
39 typedef int (*get_instance_count_proc_t) ();
40
41 static void
42 message(const char *text)
43 {
44 MessageBox(GetDesktopWindow(), text, "SeamlessRDP Shell", MB_OK);
45 }
46
47 static char *
48 get_token(char **s)
49 {
50 char *comma, *head;
51 head = *s;
52
53 if (!head)
54 return NULL;
55
56 comma = strchr(head, ',');
57 if (comma)
58 {
59 *comma = '\0';
60 *s = comma + 1;
61 }
62 else
63 {
64 *s = NULL;
65 }
66
67 return head;
68 }
69
70 static BOOL CALLBACK
71 enum_cb(HWND hwnd, LPARAM lparam)
72 {
73 RECT rect;
74 char title[150];
75 LONG styles;
76 int state;
77 HWND parent;
78
79 styles = GetWindowLong(hwnd, GWL_STYLE);
80
81 if (!(styles & WS_VISIBLE))
82 return TRUE;
83
84 if (styles & WS_POPUP)
85 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
86 else
87 parent = NULL;
88
89 vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);
90
91 if (!GetWindowRect(hwnd, &rect))
92 {
93 debug("GetWindowRect failed!");
94 return TRUE;
95 }
96
97 vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",
98 hwnd,
99 rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
100
101 GetWindowText(hwnd, title, sizeof(title));
102
103 /* FIXME: Strip title of dangerous characters */
104
105 vchannel_write("TITLE,0x%x,%s,0x%x", hwnd, title, 0);
106
107 if (styles & WS_MAXIMIZE)
108 state = 2;
109 else if (styles & WS_MINIMIZE)
110 state = 1;
111 else
112 state = 0;
113
114 vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);
115
116 return TRUE;
117 }
118
119 static void
120 do_sync(void)
121 {
122 vchannel_block();
123
124 vchannel_write("SYNCBEGIN,0x0");
125
126 EnumWindows(enum_cb, 0);
127
128 vchannel_write("SYNCEND,0x0");
129
130 vchannel_unblock();
131 }
132
133 static void
134 do_state(HWND hwnd, int state)
135 {
136 if (state == 0)
137 ShowWindow(hwnd, SW_RESTORE);
138 else if (state == 1)
139 ShowWindow(hwnd, SW_MINIMIZE);
140 else if (state == 2)
141 ShowWindow(hwnd, SW_MAXIMIZE);
142 else
143 debug("Invalid state %d sent.", state);
144 }
145
146 static void
147 do_position(HWND hwnd, int x, int y, int width, int height)
148 {
149 SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);
150 }
151
152 static void
153 do_zchange(HWND hwnd, HWND behind)
154 {
155 if (behind == NULL)
156 behind = HWND_TOP;
157 SetWindowPos(hwnd, behind, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
158 }
159
160 static void
161 process_cmds(void)
162 {
163 char line[VCHANNEL_MAX_LINE];
164 int size;
165
166 char *p, *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
167
168 while ((size = vchannel_read(line, sizeof(line))) >= 0)
169 {
170 debug("Got: %s", line);
171
172 p = line;
173
174 tok1 = get_token(&p);
175 tok2 = get_token(&p);
176 tok3 = get_token(&p);
177 tok4 = get_token(&p);
178 tok5 = get_token(&p);
179 tok6 = get_token(&p);
180 tok7 = get_token(&p);
181 tok8 = get_token(&p);
182
183 if (strcmp(tok1, "SYNC") == 0)
184 do_sync();
185 else if (strcmp(tok1, "STATE") == 0)
186 do_state((HWND) strtol(tok2, NULL, 0), strtol(tok3, NULL, 0));
187 else if (strcmp(tok1, "POSITION") == 0)
188 do_position((HWND) strtol(tok2, NULL, 0), strtol(tok3, NULL, 0),
189 strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL,
190 0));
191 else if (strcmp(tok1, "ZCHANGE") == 0)
192 do_zchange((HWND) strtol(tok2, NULL, 0), (HWND) strtol(tok3, NULL, 0));
193 }
194 }
195
196 int WINAPI
197 WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
198 {
199 HMODULE hookdll;
200
201 set_hooks_proc_t set_hooks_fn;
202 remove_hooks_proc_t remove_hooks_fn;
203 get_instance_count_proc_t instance_count_fn;
204
205 g_instance = instance;
206
207 hookdll = LoadLibrary("seamlessrdp.dll");
208 if (!hookdll)
209 {
210 message("Could not load hook DLL. Unable to continue.");
211 return -1;
212 }
213
214 set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
215 remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
216 instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
217
218 if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn)
219 {
220 FreeLibrary(hookdll);
221 message("Hook DLL doesn't contain the correct functions. Unable to continue.");
222 return -1;
223 }
224
225 /* Check if the DLL is already loaded */
226 if (instance_count_fn() != 1)
227 {
228 FreeLibrary(hookdll);
229 message("Another running instance of Seamless RDP detected.");
230 return -1;
231 }
232
233 vchannel_open();
234
235 set_hooks_fn();
236
237 /* Since we don't see the entire desktop we must resize windows
238 immediatly. */
239 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
240
241 /* Disable screen saver since we cannot catch its windows. */
242 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
243
244 if (strlen(cmdline) == 0)
245 {
246 message("No command line specified.");
247 return -1;
248 }
249 else
250 {
251 BOOL result;
252 DWORD exitcode;
253 PROCESS_INFORMATION proc_info;
254 STARTUPINFO startup_info;
255
256 memset(&startup_info, 0, sizeof(STARTUPINFO));
257 startup_info.cb = sizeof(STARTUPINFO);
258
259 result = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0,
260 NULL, NULL, &startup_info, &proc_info);
261
262 if (result)
263 {
264 do
265 {
266 process_cmds();
267 Sleep(100);
268 GetExitCodeProcess(proc_info.hProcess, &exitcode);
269 }
270 while (exitcode == STILL_ACTIVE);
271
272 // Release handles
273 CloseHandle(proc_info.hProcess);
274 CloseHandle(proc_info.hThread);
275 }
276 else
277 {
278 // CreateProcess failed.
279 char msg[256];
280 _snprintf(msg, sizeof(msg),
281 "Unable to launch the requested application:\n%s", cmdline);
282 message(msg);
283 }
284 }
285
286 remove_hooks_fn();
287
288 FreeLibrary(hookdll);
289
290 vchannel_close();
291
292 return 1;
293 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26