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

Annotation of /sourceforge.net/trunk/seamlessrdp/ServerExe/main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1185 - (hide annotations)
Wed Mar 22 11:52:07 2006 UTC (18 years, 3 months ago) by ossman_
File MIME type: text/plain
File size: 9448 byte(s)
SetActiveWindow() only does what we want when the window is owned by the
same process as the currently active. SetForegroundWindow() does what we want
under all circumstances.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26