/[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 1150 - (hide annotations)
Thu Mar 16 15:42:32 2006 UTC (18 years, 2 months ago) by ossman_
File MIME type: text/plain
File size: 8327 byte(s)
Restore system parameters info on reconnect as they get reset.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26