/[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 1165 - (show annotations)
Mon Mar 20 12:28:03 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 9100 byte(s)
Send an ACK for all client commands.

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 #include <wtsapi32.h>
28 #include <cchannel.h>
29
30 #include "vchannel.h"
31
32 #include "resource.h"
33
34 #define APP_NAME "SeamlessRDP Shell"
35
36 #ifndef WM_WTSSESSION_CHANGE
37 #define WM_WTSSESSION_CHANGE 0x02B1
38 #endif
39 #ifndef WTS_REMOTE_CONNECT
40 #define WTS_REMOTE_CONNECT 0x3
41 #endif
42
43 /* Global data */
44 static HINSTANCE g_instance;
45 static HWND g_hwnd;
46
47 typedef void (*set_hooks_proc_t) ();
48 typedef void (*remove_hooks_proc_t) ();
49 typedef int (*get_instance_count_proc_t) ();
50
51 typedef void (*move_window_proc_t) (unsigned int serial, HWND hwnd, int x, int y, int width,
52 int height);
53 typedef void (*zchange_proc_t) (unsigned int serial, HWND hwnd, HWND behind);
54 typedef void (*focus_proc_t) (unsigned int serial, HWND hwnd);
55 typedef void (*set_state_proc_t) (unsigned int serial, HWND hwnd, int state);
56
57 static move_window_proc_t g_move_window_fn = NULL;
58 static zchange_proc_t g_zchange_fn = NULL;
59 static focus_proc_t g_focus_fn = NULL;
60 static set_state_proc_t g_set_state_fn = NULL;
61
62 static void
63 message(const char *text)
64 {
65 MessageBox(GetDesktopWindow(), text, "SeamlessRDP Shell", MB_OK);
66 }
67
68 static char *
69 get_token(char **s)
70 {
71 char *comma, *head;
72 head = *s;
73
74 if (!head)
75 return NULL;
76
77 comma = strchr(head, ',');
78 if (comma)
79 {
80 *comma = '\0';
81 *s = comma + 1;
82 }
83 else
84 {
85 *s = NULL;
86 }
87
88 return head;
89 }
90
91 static BOOL CALLBACK
92 enum_cb(HWND hwnd, LPARAM lparam)
93 {
94 RECT rect;
95 unsigned short title[150];
96 LONG styles;
97 int state;
98 HWND parent;
99
100 styles = GetWindowLong(hwnd, GWL_STYLE);
101
102 if (!(styles & WS_VISIBLE))
103 return TRUE;
104
105 if (styles & WS_POPUP)
106 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
107 else
108 parent = NULL;
109
110 vchannel_write("CREATE", "0x%p,0x%p,0x%x", hwnd, parent, 0);
111
112 if (!GetWindowRect(hwnd, &rect))
113 {
114 debug("GetWindowRect failed!");
115 return TRUE;
116 }
117
118 vchannel_write("POSITION", "0x%p,%d,%d,%d,%d,0x%x",
119 hwnd,
120 rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
121
122 GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
123
124 vchannel_write("TITLE", "0x%x,%s,0x%x", hwnd, vchannel_strfilter_unicode(title), 0);
125
126 if (styles & WS_MAXIMIZE)
127 state = 2;
128 else if (styles & WS_MINIMIZE)
129 state = 1;
130 else
131 state = 0;
132
133 vchannel_write("STATE", "0x%p,0x%x,0x%x", hwnd, state, 0);
134
135 return TRUE;
136 }
137
138 static void
139 do_sync(void)
140 {
141 vchannel_block();
142
143 vchannel_write("SYNCBEGIN", "0x0");
144
145 EnumWindows(enum_cb, 0);
146
147 vchannel_write("SYNCEND", "0x0");
148
149 vchannel_unblock();
150 }
151
152 static void
153 do_state(unsigned int serial, HWND hwnd, int state)
154 {
155 g_set_state_fn(serial, hwnd, state);
156 }
157
158 static void
159 do_position(unsigned int serial, HWND hwnd, int x, int y, int width, int height)
160 {
161 g_move_window_fn(serial, hwnd, x, y, width, height);
162 }
163
164 static void
165 do_zchange(unsigned int serial, HWND hwnd, HWND behind)
166 {
167 g_zchange_fn(serial, hwnd, behind);
168 }
169
170 static void
171 do_focus(unsigned int serial, HWND hwnd)
172 {
173 g_focus_fn(serial, hwnd);
174 }
175
176 static void
177 process_cmds(void)
178 {
179 char line[VCHANNEL_MAX_LINE];
180 int size;
181
182 char *p, *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
183
184 while ((size = vchannel_read(line, sizeof(line))) >= 0)
185 {
186 p = line;
187
188 tok1 = get_token(&p);
189 tok2 = get_token(&p);
190 tok3 = get_token(&p);
191 tok4 = get_token(&p);
192 tok5 = get_token(&p);
193 tok6 = get_token(&p);
194 tok7 = get_token(&p);
195 tok8 = get_token(&p);
196
197 if (strcmp(tok1, "SYNC") == 0)
198 do_sync();
199 else if (strcmp(tok1, "STATE") == 0)
200 do_state(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0),
201 strtol(tok4, NULL, 0));
202 else if (strcmp(tok1, "POSITION") == 0)
203 do_position(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0),
204 strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL,
205 0),
206 strtol(tok7, NULL, 0));
207 else if (strcmp(tok1, "ZCHANGE") == 0)
208 do_zchange(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0),
209 (HWND) strtoul(tok4, NULL, 0));
210 else if (strcmp(tok1, "FOCUS") == 0)
211 do_focus(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0));
212 }
213 }
214
215 static LRESULT CALLBACK
216 wndproc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
217 {
218 if (message == WM_WTSSESSION_CHANGE)
219 {
220 if (wparam == WTS_REMOTE_CONNECT)
221 {
222 /* These get reset on each reconnect */
223 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
224 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
225 vchannel_write("HELLO", "0x%08x", 1);
226 }
227 }
228
229 return DefWindowProc(hwnd, message, wparam, lparam);
230 }
231
232 static BOOL
233 register_class(void)
234 {
235 WNDCLASSEX wcx;
236
237 memset(&wcx, 0, sizeof(wcx));
238
239 wcx.cbSize = sizeof(wcx);
240 wcx.lpfnWndProc = wndproc;
241 wcx.hInstance = g_instance;
242 wcx.lpszClassName = "SeamlessClass";
243
244 return RegisterClassEx(&wcx);
245 }
246
247 static BOOL
248 create_wnd(void)
249 {
250 if (!register_class())
251 return FALSE;
252
253 g_hwnd = CreateWindow("SeamlessClass",
254 "Seamless Window",
255 WS_OVERLAPPEDWINDOW,
256 CW_USEDEFAULT,
257 CW_USEDEFAULT,
258 CW_USEDEFAULT,
259 CW_USEDEFAULT, (HWND) NULL, (HMENU) NULL, g_instance, (LPVOID) NULL);
260
261 if (!g_hwnd)
262 return FALSE;
263
264 return TRUE;
265 }
266
267 int WINAPI
268 WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
269 {
270 HMODULE hookdll;
271
272 set_hooks_proc_t set_hooks_fn;
273 remove_hooks_proc_t remove_hooks_fn;
274 get_instance_count_proc_t instance_count_fn;
275
276 g_instance = instance;
277
278 hookdll = LoadLibrary("seamlessrdp.dll");
279 if (!hookdll)
280 {
281 message("Could not load hook DLL. Unable to continue.");
282 return -1;
283 }
284
285 set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
286 remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
287 instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
288 g_move_window_fn = (move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow");
289 g_zchange_fn = (zchange_proc_t) GetProcAddress(hookdll, "SafeZChange");
290 g_focus_fn = (focus_proc_t) GetProcAddress(hookdll, "SafeFocus");
291 g_set_state_fn = (set_state_proc_t) GetProcAddress(hookdll, "SafeSetState");
292
293 if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn || !g_move_window_fn
294 || !g_zchange_fn || !g_focus_fn || !g_set_state_fn)
295 {
296 FreeLibrary(hookdll);
297 message("Hook DLL doesn't contain the correct functions. Unable to continue.");
298 return -1;
299 }
300
301 /* Check if the DLL is already loaded */
302 if (instance_count_fn() != 1)
303 {
304 FreeLibrary(hookdll);
305 message("Another running instance of Seamless RDP detected.");
306 return -1;
307 }
308
309 if (!create_wnd())
310 {
311 FreeLibrary(hookdll);
312 message("Couldn't create a window to catch events.");
313 return -1;
314 }
315
316 WTSRegisterSessionNotification(g_hwnd, NOTIFY_FOR_THIS_SESSION);
317
318 vchannel_open();
319
320 vchannel_write("HELLO", "0x%08x", 0);
321
322 set_hooks_fn();
323
324 /* Since we don't see the entire desktop we must resize windows
325 immediatly. */
326 SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
327
328 /* Disable screen saver since we cannot catch its windows. */
329 SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
330
331 if (strlen(cmdline) == 0)
332 {
333 message("No command line specified.");
334 return -1;
335 }
336 else
337 {
338 BOOL result;
339 DWORD exitcode;
340 PROCESS_INFORMATION proc_info;
341 STARTUPINFO startup_info;
342 MSG msg;
343
344 memset(&startup_info, 0, sizeof(STARTUPINFO));
345 startup_info.cb = sizeof(STARTUPINFO);
346
347 result = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0,
348 NULL, NULL, &startup_info, &proc_info);
349
350 if (result)
351 {
352 do
353 {
354 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
355 {
356 TranslateMessage(&msg);
357 DispatchMessage(&msg);
358 }
359 process_cmds();
360 Sleep(100);
361 GetExitCodeProcess(proc_info.hProcess, &exitcode);
362 }
363 while (exitcode == STILL_ACTIVE);
364
365 // Release handles
366 CloseHandle(proc_info.hProcess);
367 CloseHandle(proc_info.hThread);
368 }
369 else
370 {
371 // CreateProcess failed.
372 char msg[256];
373 _snprintf(msg, sizeof(msg),
374 "Unable to launch the requested application:\n%s", cmdline);
375 message(msg);
376 }
377 }
378
379 WTSUnRegisterSessionNotification(g_hwnd);
380
381 remove_hooks_fn();
382
383 FreeLibrary(hookdll);
384
385 vchannel_close();
386
387 return 1;
388 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26