/[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 1163 - (hide annotations)
Mon Mar 20 10:31:58 2006 UTC (18 years, 2 months ago) by ossman_
File MIME type: text/plain
File size: 8976 byte(s)
Add serial numbers to protocol.

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

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.26