/[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 1153 - (hide annotations)
Fri Mar 17 09:55:35 2006 UTC (18 years, 2 months ago) by ossman_
File MIME type: text/plain
File size: 8877 byte(s)
Handle FOCUS. We need to do this via an extra message because a process is
only allowed to focus its own windows.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26