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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1071 by ossman_, Thu Mar 9 12:00:15 2006 UTC revision 1177 by ossman_, Tue Mar 21 14:42:25 2006 UTC
# Line 24  Line 24 
24    
25  #include <windows.h>  #include <windows.h>
26  #include <stdio.h>  #include <stdio.h>
27    #include <wtsapi32.h>
28    #include <cchannel.h>
29    
30    #include "vchannel.h"
31    
32  #include "resource.h"  #include "resource.h"
33    
34  #define APP_NAME "SeamlessRDP Shell"  #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 */  /* Global data */
44  static HINSTANCE g_instance;  static HINSTANCE g_instance;
45    static HWND g_hwnd;
46    
47  typedef void (*set_hooks_proc_t) ();  typedef void (*set_hooks_proc_t) ();
48  typedef void (*remove_hooks_proc_t) ();  typedef void (*remove_hooks_proc_t) ();
49  typedef int (*get_instance_count_proc_t) ();  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  static void
63  message(const char *text)  message(const char *text)
64  {  {
65          MessageBox(GetDesktopWindow(), text, "SeamlessRDP Shell", MB_OK);          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            DWORD pid;
100            int flags;
101    
102            styles = GetWindowLong(hwnd, GWL_STYLE);
103    
104            if (!(styles & WS_VISIBLE))
105                    return TRUE;
106    
107            if (styles & WS_POPUP)
108                    parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
109            else
110                    parent = NULL;
111    
112            GetWindowThreadProcessId(hwnd, &pid);
113    
114            flags = 0;
115            if (styles & DS_MODALFRAME)
116                    flags |= SEAMLESS_CREATE_MODAL;
117    
118            vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", (long) hwnd, (long) pid,
119                           (long) parent, flags);
120    
121            if (!GetWindowRect(hwnd, &rect))
122            {
123                    debug("GetWindowRect failed!");
124                    return TRUE;
125            }
126    
127            vchannel_write("POSITION", "0x%p,%d,%d,%d,%d,0x%x",
128                           hwnd,
129                           rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
130    
131            GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
132    
133            vchannel_write("TITLE", "0x%x,%s,0x%x", hwnd, vchannel_strfilter_unicode(title), 0);
134    
135            if (styles & WS_MAXIMIZE)
136                    state = 2;
137            else if (styles & WS_MINIMIZE)
138                    state = 1;
139            else
140                    state = 0;
141    
142            vchannel_write("STATE", "0x%p,0x%x,0x%x", hwnd, state, 0);
143    
144            return TRUE;
145    }
146    
147    static void
148    do_sync(void)
149    {
150            vchannel_block();
151    
152            vchannel_write("SYNCBEGIN", "0x0");
153    
154            EnumWindows(enum_cb, 0);
155    
156            vchannel_write("SYNCEND", "0x0");
157    
158            vchannel_unblock();
159    }
160    
161    static void
162    do_state(unsigned int serial, HWND hwnd, int state)
163    {
164            g_set_state_fn(serial, hwnd, state);
165    }
166    
167    static void
168    do_position(unsigned int serial, HWND hwnd, int x, int y, int width, int height)
169    {
170            g_move_window_fn(serial, hwnd, x, y, width, height);
171    }
172    
173    static void
174    do_zchange(unsigned int serial, HWND hwnd, HWND behind)
175    {
176            g_zchange_fn(serial, hwnd, behind);
177    }
178    
179    static void
180    do_focus(unsigned int serial, HWND hwnd)
181    {
182            g_focus_fn(serial, hwnd);
183    }
184    
185    static void
186    process_cmds(void)
187    {
188            char line[VCHANNEL_MAX_LINE];
189            int size;
190    
191            char *p, *tok1, *tok2, *tok3, *tok4, *tok5, *tok6, *tok7, *tok8;
192    
193            while ((size = vchannel_read(line, sizeof(line))) >= 0)
194            {
195                    p = line;
196    
197                    tok1 = get_token(&p);
198                    tok2 = get_token(&p);
199                    tok3 = get_token(&p);
200                    tok4 = get_token(&p);
201                    tok5 = get_token(&p);
202                    tok6 = get_token(&p);
203                    tok7 = get_token(&p);
204                    tok8 = get_token(&p);
205    
206                    if (strcmp(tok1, "SYNC") == 0)
207                            do_sync();
208                    else if (strcmp(tok1, "STATE") == 0)
209                            do_state(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0),
210                                     strtol(tok4, NULL, 0));
211                    else if (strcmp(tok1, "POSITION") == 0)
212                            do_position(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0),
213                                        strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL,
214                                                                                             0),
215                                        strtol(tok7, NULL, 0));
216                    else if (strcmp(tok1, "ZCHANGE") == 0)
217                            do_zchange(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0),
218                                       (HWND) strtoul(tok4, NULL, 0));
219                    else if (strcmp(tok1, "FOCUS") == 0)
220                            do_focus(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0));
221            }
222    }
223    
224    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                    {
231                            /* These get reset on each reconnect */
232                            SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
233                            SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
234                            vchannel_write("HELLO", "0x%08x", 1);
235                    }
236            }
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  int WINAPI  int WINAPI
277  WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)  WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
278  {  {
# Line 53  WinMain(HINSTANCE instance, HINSTANCE pr Line 284  WinMain(HINSTANCE instance, HINSTANCE pr
284    
285          g_instance = instance;          g_instance = instance;
286    
287          hookdll = LoadLibrary("hookdll.dll");          hookdll = LoadLibrary("seamlessrdp.dll");
288          if (!hookdll)          if (!hookdll)
289          {          {
290                  message("Could not load hook DLL. Unable to continue.");                  message("Could not load hook DLL. Unable to continue.");
# Line 63  WinMain(HINSTANCE instance, HINSTANCE pr Line 294  WinMain(HINSTANCE instance, HINSTANCE pr
294          set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");          set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
295          remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");          remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
296          instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");          instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
297            g_move_window_fn = (move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow");
298            g_zchange_fn = (zchange_proc_t) GetProcAddress(hookdll, "SafeZChange");
299            g_focus_fn = (focus_proc_t) GetProcAddress(hookdll, "SafeFocus");
300            g_set_state_fn = (set_state_proc_t) GetProcAddress(hookdll, "SafeSetState");
301    
302          if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn)          if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn || !g_move_window_fn
303                || !g_zchange_fn || !g_focus_fn || !g_set_state_fn)
304          {          {
305                  FreeLibrary(hookdll);                  FreeLibrary(hookdll);
306                  message("Hook DLL doesn't contain the correct functions. Unable to continue.");                  message("Hook DLL doesn't contain the correct functions. Unable to continue.");
# Line 79  WinMain(HINSTANCE instance, HINSTANCE pr Line 315  WinMain(HINSTANCE instance, HINSTANCE pr
315                  return -1;                  return -1;
316          }          }
317    
318            if (!create_wnd())
319            {
320                    FreeLibrary(hookdll);
321                    message("Couldn't create a window to catch events.");
322                    return -1;
323            }
324    
325            WTSRegisterSessionNotification(g_hwnd, NOTIFY_FOR_THIS_SESSION);
326    
327            vchannel_open();
328    
329            vchannel_write("HELLO", "0x%08x", 0);
330    
331          set_hooks_fn();          set_hooks_fn();
332    
333            /* Since we don't see the entire desktop we must resize windows
334               immediatly. */
335            SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
336    
337            /* Disable screen saver since we cannot catch its windows. */
338            SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
339    
340          if (strlen(cmdline) == 0)          if (strlen(cmdline) == 0)
341          {          {
342                  message("No command line specified.");                  message("No command line specified.");
# Line 92  WinMain(HINSTANCE instance, HINSTANCE pr Line 348  WinMain(HINSTANCE instance, HINSTANCE pr
348                  DWORD exitcode;                  DWORD exitcode;
349                  PROCESS_INFORMATION proc_info;                  PROCESS_INFORMATION proc_info;
350                  STARTUPINFO startup_info;                  STARTUPINFO startup_info;
351                    MSG msg;
352    
353                  memset(&startup_info, 0, sizeof(STARTUPINFO));                  memset(&startup_info, 0, sizeof(STARTUPINFO));
354                  startup_info.cb = sizeof(STARTUPINFO);                  startup_info.cb = sizeof(STARTUPINFO);
# Line 103  WinMain(HINSTANCE instance, HINSTANCE pr Line 360  WinMain(HINSTANCE instance, HINSTANCE pr
360                  {                  {
361                          do                          do
362                          {                          {
363                                  Sleep(1000);                                  while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
364                                    {
365                                            TranslateMessage(&msg);
366                                            DispatchMessage(&msg);
367                                    }
368                                    process_cmds();
369                                    Sleep(100);
370                                  GetExitCodeProcess(proc_info.hProcess, &exitcode);                                  GetExitCodeProcess(proc_info.hProcess, &exitcode);
371                          }                          }
372                          while (exitcode == STILL_ACTIVE);                          while (exitcode == STILL_ACTIVE);
# Line 122  WinMain(HINSTANCE instance, HINSTANCE pr Line 385  WinMain(HINSTANCE instance, HINSTANCE pr
385                  }                  }
386          }          }
387    
388            WTSUnRegisterSessionNotification(g_hwnd);
389    
390          remove_hooks_fn();          remove_hooks_fn();
391    
392          FreeLibrary(hookdll);          FreeLibrary(hookdll);
393    
394            vchannel_close();
395    
396          return 1;          return 1;
397  }  }

Legend:
Removed from v.1071  
changed lines
  Added in v.1177

  ViewVC Help
Powered by ViewVC 1.1.26