22 |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
23 |
*/ |
*/ |
24 |
|
|
25 |
|
#define WINVER 0x0501 |
26 |
|
|
27 |
#include <windows.h> |
#include <windows.h> |
28 |
#include <stdio.h> |
#include <stdio.h> |
29 |
#include <wtsapi32.h> |
#include <wtsapi32.h> |
50 |
typedef void (*remove_hooks_proc_t) (); |
typedef void (*remove_hooks_proc_t) (); |
51 |
typedef int (*get_instance_count_proc_t) (); |
typedef int (*get_instance_count_proc_t) (); |
52 |
|
|
53 |
typedef void (*move_window_proc_t) (HWND hwnd, int x, int y, int width, int height); |
typedef void (*move_window_proc_t) (unsigned int serial, HWND hwnd, int x, int y, int width, |
54 |
|
int height); |
55 |
|
typedef void (*zchange_proc_t) (unsigned int serial, HWND hwnd, HWND behind); |
56 |
|
typedef void (*focus_proc_t) (unsigned int serial, HWND hwnd); |
57 |
|
typedef void (*set_state_proc_t) (unsigned int serial, HWND hwnd, int state); |
58 |
|
|
59 |
static move_window_proc_t g_move_window_fn = NULL; |
static move_window_proc_t g_move_window_fn = NULL; |
60 |
|
static zchange_proc_t g_zchange_fn = NULL; |
61 |
|
static focus_proc_t g_focus_fn = NULL; |
62 |
|
static set_state_proc_t g_set_state_fn = NULL; |
63 |
|
|
64 |
static void |
static void |
65 |
message(const char *text) |
message(const char *text) |
98 |
LONG styles; |
LONG styles; |
99 |
int state; |
int state; |
100 |
HWND parent; |
HWND parent; |
101 |
|
DWORD pid; |
102 |
|
int flags; |
103 |
|
|
104 |
styles = GetWindowLong(hwnd, GWL_STYLE); |
styles = GetWindowLong(hwnd, GWL_STYLE); |
105 |
|
|
111 |
else |
else |
112 |
parent = NULL; |
parent = NULL; |
113 |
|
|
114 |
vchannel_write("CREATE,0x%p,0x%p,0x%x", hwnd, parent, 0); |
GetWindowThreadProcessId(hwnd, &pid); |
115 |
|
|
116 |
|
flags = 0; |
117 |
|
if (styles & DS_MODALFRAME) |
118 |
|
flags |= SEAMLESS_CREATE_MODAL; |
119 |
|
|
120 |
|
vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x", (long) hwnd, (long) pid, |
121 |
|
(long) parent, flags); |
122 |
|
|
123 |
if (!GetWindowRect(hwnd, &rect)) |
if (!GetWindowRect(hwnd, &rect)) |
124 |
{ |
{ |
126 |
return TRUE; |
return TRUE; |
127 |
} |
} |
128 |
|
|
129 |
vchannel_write("POSITION,0x%p,%d,%d,%d,%d,0x%x", |
vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x", |
130 |
hwnd, |
hwnd, |
131 |
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); |
132 |
|
|
133 |
GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); |
GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title)); |
134 |
|
|
135 |
vchannel_write("TITLE,0x%x,%s,0x%x", hwnd, vchannel_strfilter_unicode(title), 0); |
vchannel_write("TITLE", "0x%x,%s,0x%x", hwnd, vchannel_strfilter_unicode(title), 0); |
136 |
|
|
137 |
if (styles & WS_MAXIMIZE) |
if (styles & WS_MAXIMIZE) |
138 |
state = 2; |
state = 2; |
141 |
else |
else |
142 |
state = 0; |
state = 0; |
143 |
|
|
144 |
vchannel_write("STATE,0x%p,0x%x,0x%x", hwnd, state, 0); |
vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd, state, 0); |
145 |
|
|
146 |
return TRUE; |
return TRUE; |
147 |
} |
} |
151 |
{ |
{ |
152 |
vchannel_block(); |
vchannel_block(); |
153 |
|
|
154 |
vchannel_write("SYNCBEGIN,0x0"); |
vchannel_write("SYNCBEGIN", "0x0"); |
155 |
|
|
156 |
EnumWindows(enum_cb, 0); |
EnumWindows(enum_cb, 0); |
157 |
|
|
158 |
vchannel_write("SYNCEND,0x0"); |
vchannel_write("SYNCEND", "0x0"); |
159 |
|
|
160 |
vchannel_unblock(); |
vchannel_unblock(); |
161 |
} |
} |
162 |
|
|
163 |
static void |
static void |
164 |
do_state(HWND hwnd, int state) |
do_state(unsigned int serial, HWND hwnd, int state) |
165 |
{ |
{ |
166 |
if (state == 0) |
g_set_state_fn(serial, hwnd, state); |
|
ShowWindow(hwnd, SW_RESTORE); |
|
|
else if (state == 1) |
|
|
ShowWindow(hwnd, SW_MINIMIZE); |
|
|
else if (state == 2) |
|
|
ShowWindow(hwnd, SW_MAXIMIZE); |
|
|
else |
|
|
debug("Invalid state %d sent.", state); |
|
167 |
} |
} |
168 |
|
|
169 |
static void |
static void |
170 |
do_position(HWND hwnd, int x, int y, int width, int height) |
do_position(unsigned int serial, HWND hwnd, int x, int y, int width, int height) |
171 |
{ |
{ |
172 |
g_move_window_fn(hwnd, x, y, width, height); |
g_move_window_fn(serial, hwnd, x, y, width, height); |
173 |
} |
} |
174 |
|
|
175 |
static void |
static void |
176 |
do_zchange(HWND hwnd, HWND behind) |
do_zchange(unsigned int serial, HWND hwnd, HWND behind) |
177 |
{ |
{ |
178 |
if (behind == NULL) |
g_zchange_fn(serial, hwnd, behind); |
179 |
behind = HWND_TOP; |
} |
180 |
SetWindowPos(hwnd, behind, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); |
|
181 |
|
static void |
182 |
|
do_focus(unsigned int serial, HWND hwnd) |
183 |
|
{ |
184 |
|
g_focus_fn(serial, hwnd); |
185 |
} |
} |
186 |
|
|
187 |
static void |
static void |
208 |
if (strcmp(tok1, "SYNC") == 0) |
if (strcmp(tok1, "SYNC") == 0) |
209 |
do_sync(); |
do_sync(); |
210 |
else if (strcmp(tok1, "STATE") == 0) |
else if (strcmp(tok1, "STATE") == 0) |
211 |
do_state((HWND) strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0)); |
do_state(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0), |
212 |
|
strtol(tok4, NULL, 0)); |
213 |
else if (strcmp(tok1, "POSITION") == 0) |
else if (strcmp(tok1, "POSITION") == 0) |
214 |
do_position((HWND) strtoul(tok2, NULL, 0), strtol(tok3, NULL, 0), |
do_position(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0), |
215 |
strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL, |
strtol(tok4, NULL, 0), strtol(tok5, NULL, 0), strtol(tok6, NULL, |
216 |
0)); |
0), |
217 |
|
strtol(tok7, NULL, 0)); |
218 |
else if (strcmp(tok1, "ZCHANGE") == 0) |
else if (strcmp(tok1, "ZCHANGE") == 0) |
219 |
do_zchange((HWND) strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0)); |
do_zchange(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0), |
220 |
|
(HWND) strtoul(tok4, NULL, 0)); |
221 |
|
else if (strcmp(tok1, "FOCUS") == 0) |
222 |
|
do_focus(strtoul(tok2, NULL, 0), (HWND) strtoul(tok3, NULL, 0)); |
223 |
} |
} |
224 |
} |
} |
225 |
|
|
229 |
if (message == WM_WTSSESSION_CHANGE) |
if (message == WM_WTSSESSION_CHANGE) |
230 |
{ |
{ |
231 |
if (wparam == WTS_REMOTE_CONNECT) |
if (wparam == WTS_REMOTE_CONNECT) |
232 |
vchannel_write("HELLO,0x%08x", 1); |
{ |
233 |
|
/* These get reset on each reconnect */ |
234 |
|
SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0); |
235 |
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0); |
236 |
|
vchannel_write("HELLO", "0x%08x", 1); |
237 |
|
} |
238 |
} |
} |
239 |
|
|
240 |
return DefWindowProc(hwnd, message, wparam, lparam); |
return DefWindowProc(hwnd, message, wparam, lparam); |
297 |
remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks"); |
remove_hooks_fn = (remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks"); |
298 |
instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount"); |
instance_count_fn = (get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount"); |
299 |
g_move_window_fn = (move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow"); |
g_move_window_fn = (move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow"); |
300 |
|
g_zchange_fn = (zchange_proc_t) GetProcAddress(hookdll, "SafeZChange"); |
301 |
|
g_focus_fn = (focus_proc_t) GetProcAddress(hookdll, "SafeFocus"); |
302 |
|
g_set_state_fn = (set_state_proc_t) GetProcAddress(hookdll, "SafeSetState"); |
303 |
|
|
304 |
if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn || !g_move_window_fn) |
if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn || !g_move_window_fn |
305 |
|
|| !g_zchange_fn || !g_focus_fn || !g_set_state_fn) |
306 |
{ |
{ |
307 |
FreeLibrary(hookdll); |
FreeLibrary(hookdll); |
308 |
message("Hook DLL doesn't contain the correct functions. Unable to continue."); |
message("Hook DLL doesn't contain the correct functions. Unable to continue."); |
328 |
|
|
329 |
vchannel_open(); |
vchannel_open(); |
330 |
|
|
331 |
vchannel_write("HELLO,0x%08x", 0); |
vchannel_write("HELLO", "0x%08x", 0); |
332 |
|
|
333 |
set_hooks_fn(); |
set_hooks_fn(); |
334 |
|
|
339 |
/* Disable screen saver since we cannot catch its windows. */ |
/* Disable screen saver since we cannot catch its windows. */ |
340 |
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0); |
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0); |
341 |
|
|
342 |
|
/* We don't want windows denying requests to activate windows. */ |
343 |
|
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0); |
344 |
|
|
345 |
if (strlen(cmdline) == 0) |
if (strlen(cmdline) == 0) |
346 |
{ |
{ |
347 |
message("No command line specified."); |
message("No command line specified."); |