/[rdesktop]/sourceforge.net/trunk/seamlessrdp/ServerExe/HookDll/hookdll.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/HookDll/hookdll.c

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

revision 1145 by ossman_, Thu Mar 16 13:24:18 2006 UTC revision 1179 by ossman_, Tue Mar 21 14:58:29 2006 UTC
# Line 45  Line 45 
45  int g_instance_count SHARED = 0;  int g_instance_count SHARED = 0;
46    
47  // blocks for locally generated events  // blocks for locally generated events
48    HWND g_block_move_hwnd SHARED = NULL;
49    unsigned int g_block_move_serial SHARED = 0;
50  RECT g_block_move SHARED = { 0, 0, 0, 0 };  RECT g_block_move SHARED = { 0, 0, 0, 0 };
51    
52    unsigned int g_blocked_zchange_serial SHARED = 0;
53    HWND g_blocked_zchange[2] SHARED = { NULL, NULL };
54    
55    unsigned int g_blocked_focus_serial SHARED = 0;
56    HWND g_blocked_focus SHARED = NULL;
57    
58    unsigned int g_blocked_state_serial SHARED = 0;
59    HWND g_blocked_state_hwnd SHARED = NULL;
60    int g_blocked_state SHARED = -1;
61    
62  #pragma data_seg ()  #pragma data_seg ()
63    
64  #pragma comment(linker, "/section:SHAREDDATA,rws")  #pragma comment(linker, "/section:SHAREDDATA,rws")
65    
66    #define FOCUS_MSG_NAME "WM_SEAMLESS_FOCUS"
67    static UINT g_wm_seamless_focus;
68    
69  static HHOOK g_cbt_hook = NULL;  static HHOOK g_cbt_hook = NULL;
70  static HHOOK g_wndproc_hook = NULL;  static HHOOK g_wndproc_hook = NULL;
71  static HHOOK g_wndprocret_hook = NULL;  static HHOOK g_wndprocret_hook = NULL;
# Line 63  static void Line 78  static void
78  update_position(HWND hwnd)  update_position(HWND hwnd)
79  {  {
80          RECT rect, blocked;          RECT rect, blocked;
81            HWND blocked_hwnd;
82            unsigned int serial;
83    
84            WaitForSingleObject(g_mutex, INFINITE);
85            blocked_hwnd = g_block_move_hwnd;
86            serial = g_block_move_serial;
87            memcpy(&blocked, &g_block_move, sizeof(RECT));
88            ReleaseMutex(g_mutex);
89    
90            vchannel_block();
91    
92          if (!GetWindowRect(hwnd, &rect))          if (!GetWindowRect(hwnd, &rect))
93          {          {
94                  debug("GetWindowRect failed!\n");                  debug("GetWindowRect failed!\n");
95                  return;                  goto end;
96          }          }
97    
98          WaitForSingleObject(g_mutex, INFINITE);          if ((hwnd == blocked_hwnd) && (rect.left == blocked.left) && (rect.top == blocked.top)
         memcpy(&blocked, &g_block_move, sizeof(RECT));  
         ReleaseMutex(g_mutex);  
   
         if ((rect.left == blocked.left) && (rect.top == blocked.top)  
99              && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))              && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))
100                  return;                  goto end;
101    
102          vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x",          vchannel_write("POSITION", "0x%p,%d,%d,%d,%d,0x%x",
103                         hwnd,                         hwnd,
104                         rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);                         rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);
105    
106          end:
107            vchannel_unblock();
108    }
109    
110    static void
111    update_zorder(HWND hwnd)
112    {
113            HWND behind;
114            HWND block_hwnd, block_behind;
115            unsigned int serial;
116    
117            WaitForSingleObject(g_mutex, INFINITE);
118            serial = g_blocked_zchange_serial;
119            block_hwnd = g_blocked_zchange[0];
120            block_behind = g_blocked_zchange[1];
121            ReleaseMutex(g_mutex);
122    
123            vchannel_block();
124    
125            behind = GetNextWindow(hwnd, GW_HWNDPREV);
126            while (behind)
127            {
128                    LONG style;
129    
130                    style = GetWindowLong(behind, GWL_STYLE);
131    
132                    if ((!(style & WS_CHILD) || (style & WS_POPUP)) && (style & WS_VISIBLE))
133                            break;
134    
135                    behind = GetNextWindow(behind, GW_HWNDPREV);
136            }
137    
138            if ((hwnd == block_hwnd) && (behind == block_behind))
139                    vchannel_write("ACK", "%u", serial);
140            else
141                    vchannel_write("ZCHANGE", "0x%p,0x%p,0x%x", hwnd, behind, 0);
142    
143            vchannel_unblock();
144    }
145    
146    static HWND
147    get_parent(HWND hwnd)
148    {
149            LONG style;
150            HWND parent;
151    
152            style = GetWindowLong(hwnd, GWL_STYLE);
153    
154            if (style & (WS_POPUP | DS_MODALFRAME))
155            {
156                    parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);
157    
158                    if (parent)
159                    {
160                            style = GetWindowLong(parent, GWL_STYLE);
161                            if (((style & WS_CHILD) && !(style & WS_POPUP)) || !(style & WS_VISIBLE))
162                                    parent = NULL;
163                    }
164    
165                    if (!parent)
166                            parent = GetWindow(hwnd, GW_OWNER);
167    
168                    if (parent)
169                    {
170                            style = GetWindowLong(parent, GWL_STYLE);
171                            if (((style & WS_CHILD) && !(style & WS_POPUP)) || !(style & WS_VISIBLE))
172                                    parent = NULL;
173                    }
174    
175                    if (!parent)
176                            parent = (HWND) - 1;
177            }
178            else
179                    parent = NULL;
180    
181            return parent;
182  }  }
183    
184  static LRESULT CALLBACK  static LRESULT CALLBACK
# Line 108  wndproc_hook_proc(int code, WPARAM cur_t Line 206  wndproc_hook_proc(int code, WPARAM cur_t
206          if ((style & WS_CHILD) && !(style & WS_POPUP))          if ((style & WS_CHILD) && !(style & WS_POPUP))
207                  goto end;                  goto end;
208    
209          if (style & WS_POPUP)          parent = get_parent(hwnd);
         {  
                 parent = (HWND) GetWindowLong(hwnd, GWL_HWNDPARENT);  
                 if (!parent)  
                         parent = (HWND) - 1;  
         }  
         else  
                 parent = NULL;  
210    
211          switch (msg)          switch (msg)
212          {          {
   
213                  case WM_WINDOWPOSCHANGED:                  case WM_WINDOWPOSCHANGED:
214                          {                          {
215                                  WINDOWPOS *wp = (WINDOWPOS *) lparam;                                  WINDOWPOS *wp = (WINDOWPOS *) lparam;
# Line 128  wndproc_hook_proc(int code, WPARAM cur_t Line 218  wndproc_hook_proc(int code, WPARAM cur_t
218                                  {                                  {
219                                          unsigned short title[150];                                          unsigned short title[150];
220                                          int state;                                          int state;
221                                            DWORD pid;
222                                            int flags;
223    
224                                          vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0);                                          GetWindowThreadProcessId(hwnd, &pid);
225    
226                                            flags = 0;
227                                            if (style & DS_MODALFRAME)
228                                                    flags |= SEAMLESS_CREATE_MODAL;
229    
230                                            vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x",
231                                                           (long) hwnd, (long) pid, (long) parent,
232                                                           flags);
233    
234                                          GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));                                          GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
235    
236                                          vchannel_write("TITLE,0x%x,%s,0x%x", hwnd,                                          vchannel_write("TITLE", "0x%x,%s,0x%x", hwnd,
237                                                         vchannel_strfilter_unicode(title), 0);                                                         vchannel_strfilter_unicode(title), 0);
238    
239                                          if (style & WS_MAXIMIZE)                                          if (style & WS_MAXIMIZE)
# Line 145  wndproc_hook_proc(int code, WPARAM cur_t Line 245  wndproc_hook_proc(int code, WPARAM cur_t
245    
246                                          update_position(hwnd);                                          update_position(hwnd);
247    
248                                          vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0);                                          vchannel_write("STATE", "0x%p,0x%x,0x%x", hwnd, state, 0);
249                                  }                                  }
250    
251                                  if (wp->flags & SWP_HIDEWINDOW)                                  if (wp->flags & SWP_HIDEWINDOW)
252                                          vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);                                          vchannel_write("DESTROY", "0x%p,0x%x", hwnd, 0);
253    
254                                  if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))                                  if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
255                                          break;                                          break;
# Line 157  wndproc_hook_proc(int code, WPARAM cur_t Line 257  wndproc_hook_proc(int code, WPARAM cur_t
257                                  if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))                                  if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
258                                          update_position(hwnd);                                          update_position(hwnd);
259    
                                 if (!(wp->flags & SWP_NOZORDER))  
                                 {  
                                         vchannel_write("ZCHANGE,0x%p,0x%p,0x%x",  
                                                        hwnd,  
                                                        wp->flags & SWP_NOACTIVATE ? wp->  
                                                        hwndInsertAfter : 0, 0);  
                                 }  
   
260                                  break;                                  break;
261                          }                          }
262    
# Line 183  wndproc_hook_proc(int code, WPARAM cur_t Line 275  wndproc_hook_proc(int code, WPARAM cur_t
275                  case WM_DESTROY:                  case WM_DESTROY:
276                          if (!(style & WS_VISIBLE))                          if (!(style & WS_VISIBLE))
277                                  break;                                  break;
278                          vchannel_write("DESTROY,0x%p,0x%x", hwnd, 0);                          vchannel_write("DESTROY", "0x%p,0x%x", hwnd, 0);
279                          break;                          break;
280    
281                  default:                  default:
# Line 219  wndprocret_hook_proc(int code, WPARAM cu Line 311  wndprocret_hook_proc(int code, WPARAM cu
311          if ((style & WS_CHILD) && !(style & WS_POPUP))          if ((style & WS_CHILD) && !(style & WS_POPUP))
312                  goto end;                  goto end;
313    
314            parent = get_parent(hwnd);
315    
316          switch (msg)          switch (msg)
317          {          {
318                    case WM_WINDOWPOSCHANGED:
319                            {
320                                    WINDOWPOS *wp = (WINDOWPOS *) lparam;
321    
322                                    if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
323                                            break;
324    
325                                    if (!(wp->flags & SWP_NOZORDER))
326                                            update_zorder(hwnd);
327    
328                                    break;
329                            }
330    
331    
332                  case WM_SETTEXT:                  case WM_SETTEXT:
333                          {                          {
334                                  unsigned short title[150];                                  unsigned short title[150];
# Line 229  wndprocret_hook_proc(int code, WPARAM cu Line 337  wndprocret_hook_proc(int code, WPARAM cu
337                                  /* We cannot use the string in lparam because                                  /* We cannot use the string in lparam because
338                                     we need unicode. */                                     we need unicode. */
339                                  GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));                                  GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
340                                  vchannel_write("TITLE,0x%p,%s,0x%x", hwnd,                                  vchannel_write("TITLE", "0x%p,%s,0x%x", hwnd,
341                                                 vchannel_strfilter_unicode(title), 0);                                                 vchannel_strfilter_unicode(title), 0);
342                                  break;                                  break;
343                          }                          }
# Line 238  wndprocret_hook_proc(int code, WPARAM cu Line 346  wndprocret_hook_proc(int code, WPARAM cu
346                          break;                          break;
347          }          }
348    
349            if (msg == g_wm_seamless_focus)
350            {
351                    /* FIXME: SetActiveWindow() kills menus. Need to find a clean
352                       way to solve this. */
353                    if ((GetActiveWindow() != hwnd) && !parent)
354                            SetActiveWindow(hwnd);
355    
356                    vchannel_write("ACK", "%u", g_blocked_focus_serial);
357            }
358    
359        end:        end:
360          return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details);          return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details);
361  }  }
# Line 252  cbt_hook_proc(int code, WPARAM wparam, L Line 370  cbt_hook_proc(int code, WPARAM wparam, L
370          {          {
371                  case HCBT_MINMAX:                  case HCBT_MINMAX:
372                          {                          {
373                                  int show, state;                                  int show, state, blocked;
374                                    HWND blocked_hwnd;
375                                    unsigned int serial;
376    
377                                    WaitForSingleObject(g_mutex, INFINITE);
378                                    blocked_hwnd = g_blocked_state_hwnd;
379                                    serial = g_blocked_state_serial;
380                                    blocked = g_blocked_state;
381                                    ReleaseMutex(g_mutex);
382    
383                                  show = LOWORD(lparam);                                  show = LOWORD(lparam);
384    
# Line 268  cbt_hook_proc(int code, WPARAM wparam, L Line 394  cbt_hook_proc(int code, WPARAM wparam, L
394                                          debug("Unexpected show: %d", show);                                          debug("Unexpected show: %d", show);
395                                          break;                                          break;
396                                  }                                  }
397                                  vchannel_write("STATE,0x%p,0x%x,0x%x", (HWND) wparam, state, 0);  
398                                    if ((blocked_hwnd == (HWND) wparam) && (blocked == state))
399                                            vchannel_write("ACK", "%u", serial);
400                                    else
401                                            vchannel_write("STATE", "0x%p,0x%x,0x%x", (HWND) wparam,
402                                                           state, 0);
403    
404                                  break;                                  break;
405                          }                          }
406    
# Line 308  RemoveHooks(void) Line 440  RemoveHooks(void)
440  }  }
441    
442  DLL_EXPORT void  DLL_EXPORT void
443  SafeMoveWindow(HWND hwnd, int x, int y, int width, int height)  SafeMoveWindow(unsigned int serial, HWND hwnd, int x, int y, int width, int height)
444  {  {
445            RECT rect;
446    
447          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
448            g_block_move_hwnd = hwnd;
449            g_block_move_serial = serial;
450          g_block_move.left = x;          g_block_move.left = x;
451          g_block_move.top = y;          g_block_move.top = y;
452          g_block_move.right = x + width;          g_block_move.right = x + width;
# Line 319  SafeMoveWindow(HWND hwnd, int x, int y, Line 455  SafeMoveWindow(HWND hwnd, int x, int y,
455    
456          SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);          SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);
457    
458            vchannel_write("ACK", "%u", serial);
459    
460            if (!GetWindowRect(hwnd, &rect))
461                    debug("GetWindowRect failed!\n");
462            else if ((rect.left != x) || (rect.top != y) || (rect.right != x + width)
463                     || (rect.bottom != y + height))
464                    update_position(hwnd);
465    
466          WaitForSingleObject(g_mutex, INFINITE);          WaitForSingleObject(g_mutex, INFINITE);
467            g_block_move_hwnd = NULL;
468          memset(&g_block_move, 0, sizeof(RECT));          memset(&g_block_move, 0, sizeof(RECT));
469          ReleaseMutex(g_mutex);          ReleaseMutex(g_mutex);
470  }  }
471    
472    DLL_EXPORT void
473    SafeZChange(unsigned int serial, HWND hwnd, HWND behind)
474    {
475            WaitForSingleObject(g_mutex, INFINITE);
476            g_blocked_zchange_serial = serial;
477            g_blocked_zchange[0] = hwnd;
478            g_blocked_zchange[1] = behind;
479            ReleaseMutex(g_mutex);
480    
481            if (behind == NULL)
482                    behind = HWND_TOP;
483    
484            SetWindowPos(hwnd, behind, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);
485    
486            WaitForSingleObject(g_mutex, INFINITE);
487            g_blocked_zchange[0] = NULL;
488            g_blocked_zchange[1] = NULL;
489            ReleaseMutex(g_mutex);
490    }
491    
492    DLL_EXPORT void
493    SafeFocus(unsigned int serial, HWND hwnd)
494    {
495            WaitForSingleObject(g_mutex, INFINITE);
496            g_blocked_focus_serial = serial;
497            g_blocked_focus = hwnd;
498            ReleaseMutex(g_mutex);
499    
500            SendMessage(hwnd, g_wm_seamless_focus, 0, 0);
501    
502            WaitForSingleObject(g_mutex, INFINITE);
503            g_blocked_focus = NULL;
504            ReleaseMutex(g_mutex);
505    }
506    
507    DLL_EXPORT void
508    SafeSetState(unsigned int serial, HWND hwnd, int state)
509    {
510            LONG style;
511            int curstate;
512    
513            vchannel_block();
514    
515            style = GetWindowLong(hwnd, GWL_STYLE);
516    
517            if (style & WS_MAXIMIZE)
518                    curstate = 2;
519            else if (style & WS_MINIMIZE)
520                    curstate = 1;
521            else
522                    curstate = 0;
523    
524            if (state == curstate)
525            {
526                    vchannel_write("ACK", "%u", serial);
527                    vchannel_unblock();
528                    return;
529            }
530    
531            WaitForSingleObject(g_mutex, INFINITE);
532            g_blocked_state_hwnd = hwnd;
533            g_blocked_state_serial = serial;
534            g_blocked_state = state;
535            ReleaseMutex(g_mutex);
536    
537            vchannel_unblock();
538    
539            if (state == 0)
540                    ShowWindow(hwnd, SW_RESTORE);
541            else if (state == 1)
542                    ShowWindow(hwnd, SW_MINIMIZE);
543            else if (state == 2)
544                    ShowWindow(hwnd, SW_MAXIMIZE);
545            else
546                    debug("Invalid state %d sent.", state);
547    
548            WaitForSingleObject(g_mutex, INFINITE);
549            g_blocked_state_hwnd = NULL;
550            g_blocked_state = -1;
551            ReleaseMutex(g_mutex);
552    }
553    
554  DLL_EXPORT int  DLL_EXPORT int
555  GetInstanceCount()  GetInstanceCount()
556  {  {
# Line 347  DllMain(HINSTANCE hinstDLL, DWORD ul_rea Line 574  DllMain(HINSTANCE hinstDLL, DWORD ul_rea
574                          ++g_instance_count;                          ++g_instance_count;
575                          ReleaseMutex(g_mutex);                          ReleaseMutex(g_mutex);
576    
577                            g_wm_seamless_focus = RegisterWindowMessage(FOCUS_MSG_NAME);
578    
579                          vchannel_open();                          vchannel_open();
580    
581                          break;                          break;

Legend:
Removed from v.1145  
changed lines
  Added in v.1179

  ViewVC Help
Powered by ViewVC 1.1.26