Ejemplo n.º 1
0
static LRESULT CALLBACK
cbt_hook_proc(int code, WPARAM wparam, LPARAM lparam)
{
    if (!g_wm_seamless_focus)
        goto end;

    if (code < 0)
        goto end;

    switch (code) {
    case HCBT_MINMAX:
    {
        int show, state, blocked;
        HWND hwnd, blocked_hwnd;
        unsigned int serial;
        LONG style;

        WaitForSingleObject(g_mutex, INFINITE);
        blocked_hwnd = long_to_hwnd(g_shdata->blocked_state_hwnd);
        serial = g_shdata->blocked_state_serial;
        blocked = g_shdata->blocked_state;
        ReleaseMutex(g_mutex);

        hwnd = (HWND) wparam;

        style = GetWindowLong(hwnd, GWL_STYLE);

        if (!(style & WS_VISIBLE))
            break;

        show = LOWORD(lparam);

        if ((show == SW_NORMAL) || (show == SW_SHOWNORMAL)
                || (show == SW_RESTORE))
            state = 0;
        else if ((show == SW_MINIMIZE) || (show == SW_SHOWMINIMIZED))
            state = 1;
        else if ((show == SW_MAXIMIZE) || (show == SW_SHOWMAXIMIZED))
            state = 2;
        else {
            debug("Unexpected show: %d", show);
            break;
        }

        if ((blocked_hwnd == hwnd) && (blocked == state))
            vchannel_write("ACK", "%u", serial);
        else
            vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x",
                           hwnd, state, 0);

        break;
    }

    default:
        break;
    }

end:
    return CallNextHookEx(g_cbt_hook, code, wparam, lparam);
}
Ejemplo n.º 2
0
DLL_EXPORT void
SafeMoveWindow(unsigned int serial, HWND hwnd, int x, int y, int width, int height)
{
	RECT rect;

	if (IsZoomed(hwnd))
		return;

	WaitForSingleObject(g_mutex, INFINITE);
	g_block_move_hwnd = hwnd;
	g_block_move_serial = serial;
	g_block_move.left = x;
	g_block_move.top = y;
	g_block_move.right = x + width;
	g_block_move.bottom = y + height;
	ReleaseMutex(g_mutex);

	SetWindowPos(hwnd, NULL, x, y, width, height, SWP_NOACTIVATE | SWP_NOZORDER);

	vchannel_write("ACK", "%u", serial);

	if (!GetWindowRect(hwnd, &rect))
		debug("GetWindowRect failed!\n");
	else if ((rect.left != x) || (rect.top != y) || (rect.right != x + width)
		 || (rect.bottom != y + height))
		update_position(hwnd);
	else if (! IsIconic(hwnd))
		vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x", hwnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);

	WaitForSingleObject(g_mutex, INFINITE);
	g_block_move_hwnd = NULL;
	memset(&g_block_move, 0, sizeof(RECT));
	ReleaseMutex(g_mutex);
}
Ejemplo n.º 3
0
static void
do_sync(void)
{
	vchannel_write("SYNCBEGIN", "0x0");

	EnumWindows(enum_cb, 0);

	vchannel_write("SYNCEND", "0x0");
}
Ejemplo n.º 4
0
static void destroy_window(HWND hwnd)
{
	if (! removeHWNDFromHistory(hwnd))
		return;

	vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0);
}
Ejemplo n.º 5
0
static void
update_position(HWND hwnd)
{
    RECT rect, blocked;
    HWND blocked_hwnd;
    unsigned int serial;

    WaitForSingleObject(g_mutex, INFINITE);
    blocked_hwnd = long_to_hwnd(g_shdata->block_move_hwnd);
    serial = g_shdata->block_move_serial;
    memcpy(&blocked, &g_shdata->block_move, sizeof(RECT));
    ReleaseMutex(g_mutex);

    vchannel_block();

    if (!GetWindowRect(hwnd, &rect)) {
        debug("GetWindowRect failed!");
        goto end;
    }

    if ((hwnd == blocked_hwnd) && (rect.left == blocked.left)
            && (rect.top == blocked.top)
            && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))
        goto end;

    vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x",
                   hwnd,
                   rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);

end:
    vchannel_unblock();
}
Ejemplo n.º 6
0
static void
update_icon(HWND hwnd, HICON icon, int large)
{
    int i, j, size, chunks;
    char buf[32 * 32 * 4];
    char asciibuf[ICON_CHUNK * 2 + 1];

    size = extract_icon(icon, buf, sizeof(buf));
    if (size <= 0)
        return;

    if ((!large && size != 16 * 16 * 4) || (large && size != 32 * 32 * 4)) {
        debug("Unexpected icon size.");
        return;
    }

    chunks = (size + ICON_CHUNK - 1) / ICON_CHUNK;
    for (i = 0; i < chunks; i++) {
        for (j = 0; j < ICON_CHUNK; j++) {
            if (i * ICON_CHUNK + j >= size)
                break;
            sprintf(asciibuf + j * 2, "%02x",
                    (int) (unsigned char) buf[i * ICON_CHUNK + j]);
        }

        vchannel_write("SETICON", "0x%08lx,%d,RGBA,%d,%d,%s", hwnd, i,
                       large ? 32 : 16, large ? 32 : 16, asciibuf);
    }
}
Ejemplo n.º 7
0
EXTERN void
SafeMoveWindow(unsigned int serial, HWND hwnd, int x, int y, int width,
               int height)
{
    RECT rect;

    if (!g_wm_seamless_focus)
        return;

    WaitForSingleObject(g_mutex, INFINITE);
    g_shdata->block_move_hwnd = hwnd_to_long(hwnd);
    g_shdata->block_move_serial = serial;
    g_shdata->block_move.left = x;
    g_shdata->block_move.top = y;
    g_shdata->block_move.right = x + width;
    g_shdata->block_move.bottom = y + height;
    ReleaseMutex(g_mutex);

    SetWindowPos(hwnd, NULL, x, y, width, height,
                 SWP_NOACTIVATE | SWP_NOZORDER);

    vchannel_write("ACK", "%u", serial);

    if (!GetWindowRect(hwnd, &rect))
        debug("GetWindowRect failed!");
    else if ((rect.left != x) || (rect.top != y) || (rect.right != x + width)
             || (rect.bottom != y + height))
        update_position(hwnd);

    WaitForSingleObject(g_mutex, INFINITE);
    g_shdata->block_move_hwnd = 0;
    memset(&g_shdata->block_move, 0, sizeof(RECT));
    ReleaseMutex(g_mutex);
}
Ejemplo n.º 8
0
static void
update_zorder(HWND hwnd)
{
	HWND behind;
	HWND block_hwnd, block_behind;
	unsigned int serial;

	WaitForSingleObject(g_mutex, INFINITE);
	serial = g_blocked_zchange_serial;
	block_hwnd = g_blocked_zchange[0];
	block_behind = g_blocked_zchange[1];
	ReleaseMutex(g_mutex);

	vchannel_block();

	behind = GetNextWindow(hwnd, GW_HWNDPREV);
	while (behind)
	{
		LONG style;

		style = GetWindowLong(behind, GWL_STYLE);

		if ((!(style & WS_CHILD) || (style & WS_POPUP)) && (style & WS_VISIBLE))
			break;

		behind = GetNextWindow(behind, GW_HWNDPREV);
	}

	if ((hwnd == block_hwnd) && (behind == block_behind))
		vchannel_write("ACK", "%u", serial);
	else
	{
		int flags = 0;
		LONG exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
		// handle always on top
		if (exstyle & WS_EX_TOPMOST)
			flags |= SEAMLESS_CREATE_TOPMOST;
		vchannel_write("ZCHANGE", "0x%08lx,0x%08lx,0x%08x", hwnd, behind, flags);
	}

	vchannel_unblock();
}
Ejemplo n.º 9
0
static void SeamlessChannel_process_start_app(char *cmdline, unsigned int token) {
	PROCESS_INFORMATION proc_info;
	STARTUPINFO startup_info;
	BOOL pid;
	memset(&startup_info, 0, sizeof(STARTUPINFO));
	startup_info.cb = sizeof(STARTUPINFO);

	pid = CreateProcess(NULL, cmdline, NULL, NULL, FALSE, 0,
			       NULL, NULL, &startup_info, &proc_info);
	if (! pid)
	{
		vchannel_write("APP_ID", "0x%08x,0x%08x", token, -1);
		return;
	}

	vchannel_write("APP_ID", "0x%08x,0x%08x", token, proc_info.dwProcessId);
	// Release handles
	CloseHandle(proc_info.hProcess);
	CloseHandle(proc_info.hThread);
}
Ejemplo n.º 10
0
static void
update_position(HWND hwnd)
{
	RECT rect, blocked;
	HWND blocked_hwnd;
	unsigned int serial;

	WaitForSingleObject(g_mutex, INFINITE);
	blocked_hwnd = g_block_move_hwnd;
	serial = g_block_move_serial;
	memcpy(&blocked, &g_block_move, sizeof(RECT));
	ReleaseMutex(g_mutex);

	vchannel_block();

	if (IsZoomed(hwnd) || IsIconic(hwnd))
	{
		goto end;
	}
	else
	{
		if (!GetWindowRect(hwnd, &rect))
		{
			debug("GetWindowRect failed!\n");
			goto end;
		}
	}

	if ((hwnd == blocked_hwnd) && (rect.left == blocked.left) && (rect.top == blocked.top)
	    && (rect.right == blocked.right) && (rect.bottom == blocked.bottom))
		goto end;

	if ((! IsZoomed(hwnd)) && (rect.left < 0 || rect.top < 0 || rect.bottom > g_screen_height || rect.right > g_screen_width)) {
		int w = rect.right - rect.left;
		int h = rect.bottom - rect.top;
		int x = ((g_screen_width - rect.left) < w) ? (g_screen_width - w) : rect.left;
		int y = ((g_screen_height - rect.top) < h) ? (g_screen_height - h) : rect.top;
		x = (rect.left < 0) ? 0 : x;
		y = (rect.top < 0) ? 0 : y;

		SetWindowPos(hwnd, NULL, x, y, w, h, SWP_NOACTIVATE | SWP_NOZORDER);

		goto end;
	}

	vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x",
		       hwnd,
		       rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);

      end:
	vchannel_unblock();
}
Ejemplo n.º 11
0
BOOL APIENTRY
DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
			// remember our instance handle
			g_instance = hinstDLL;

			g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");
			if (!g_mutex)
				return FALSE;

			WaitForSingleObject(g_mutex, INFINITE);
			++g_instance_count;
			ReleaseMutex(g_mutex);

			g_wm_seamless_focus_request = RegisterWindowMessage(FOCUS_REQUEST_MSG_NAME);
			g_wm_seamless_focus_release = RegisterWindowMessage(FOCUS_RELEASE_MSG_NAME);

			g_internal_window = get_internal_window();

			vchannel_open();
			getScreenSize();

			break;

		case DLL_THREAD_ATTACH:
			break;

		case DLL_THREAD_DETACH:
			break;

		case DLL_PROCESS_DETACH:
			vchannel_write("DESTROYGRP", "0x%08lx, 0x%08lx", GetCurrentProcessId(), 0);

			WaitForSingleObject(g_mutex, INFINITE);
			--g_instance_count;
			ReleaseMutex(g_mutex);

			vchannel_close();

			CloseHandle(g_mutex);

			break;
	}

	return TRUE;
}
Ejemplo n.º 12
0
EXTERN void
SafeSetState(unsigned int serial, HWND hwnd, int state)
{
    LONG style;
    int curstate;

    if (!g_wm_seamless_focus)
        return;

    vchannel_block();

    style = GetWindowLong(hwnd, GWL_STYLE);

    if (style & WS_MAXIMIZE)
        curstate = 2;
    else if (style & WS_MINIMIZE)
        curstate = 1;
    else
        curstate = 0;

    if (state == curstate) {
        vchannel_write("ACK", "%u", serial);
        vchannel_unblock();
        return;
    }

    WaitForSingleObject(g_mutex, INFINITE);
    g_shdata->blocked_state_hwnd = hwnd_to_long(hwnd);
    g_shdata->blocked_state_serial = serial;
    g_shdata->blocked_state = state;
    ReleaseMutex(g_mutex);

    vchannel_unblock();

    if (state == 0)
        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);

    WaitForSingleObject(g_mutex, INFINITE);
    g_shdata->blocked_state_hwnd = 0;
    g_shdata->blocked_state = -1;
    ReleaseMutex(g_mutex);
}
Ejemplo n.º 13
0
static LRESULT CALLBACK
wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details)
{
    HWND hwnd;
    UINT msg;
    WPARAM wparam;
    LPARAM lparam;

    LONG style;

    if (!g_wm_seamless_focus)
        goto end;

    if (code < 0)
        goto end;

    hwnd = ((CWPRETSTRUCT *) details)->hwnd;
    msg = ((CWPRETSTRUCT *) details)->message;
    wparam = ((CWPRETSTRUCT *) details)->wParam;
    lparam = ((CWPRETSTRUCT *) details)->lParam;

    if (!is_toplevel(hwnd)) {
        goto end;
    }

    style = GetWindowLong(hwnd, GWL_STYLE);

    switch (msg) {
    case WM_WINDOWPOSCHANGED:
    {
        WINDOWPOS *wp = (WINDOWPOS *) lparam;

        if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
            break;

        if (!(wp->flags & SWP_NOZORDER))
            update_zorder(hwnd);

        break;
    }


    case WM_SETTEXT:
    {
        unsigned short title[150];
        if (!(style & WS_VISIBLE))
            break;
        /* We cannot use the string in lparam because
           we need unicode. */
        GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));
        vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd,
                       vchannel_strfilter_unicode(title), 0);
        break;
    }

    case WM_SETICON:
    {
        HICON icon;
        if (!(style & WS_VISIBLE))
            break;

        /*
         * Somehow, we never get WM_SETICON for the small icon.
         * So trigger a read of it every time the large one is
         * changed.
         */
        icon = get_icon(hwnd, 0);
        if (icon) {
            update_icon(hwnd, icon, 0);
            DeleteObject(icon);
        }
    }

    default:
        break;
    }

    if (msg == g_wm_seamless_focus) {
        /* For some reason, SetForegroundWindow() on menus
           closes them. Ignore focus requests for menu windows. */
        if ((GetForegroundWindow() != hwnd) && !is_menu(hwnd))
            SetForegroundWindow(hwnd);

        vchannel_write("ACK", "%u", g_shdata->blocked_focus_serial);
    }

end:
    return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details);
}
Ejemplo n.º 14
0
static LRESULT CALLBACK
wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
{
    HWND hwnd;
    UINT msg;
    WPARAM wparam;
    LPARAM lparam;

    LONG style;

    if (!g_wm_seamless_focus)
        goto end;

    if (code < 0)
        goto end;

    hwnd = ((CWPSTRUCT *) details)->hwnd;
    msg = ((CWPSTRUCT *) details)->message;
    wparam = ((CWPSTRUCT *) details)->wParam;
    lparam = ((CWPSTRUCT *) details)->lParam;

    if (!is_toplevel(hwnd)) {
        goto end;
    }

    style = GetWindowLong(hwnd, GWL_STYLE);

    switch (msg) {
    case WM_WINDOWPOSCHANGED:
    {
        WINDOWPOS *wp = (WINDOWPOS *) lparam;

        if (wp->flags & SWP_SHOWWINDOW) {
            unsigned short title[150];
            int state;
            DWORD pid;
            int flags;
            HICON icon;
            LONG exstyle;

            exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
            GetWindowThreadProcessId(hwnd, &pid);

            flags = 0;
            if (style & DS_MODALFRAME)
                flags |= SEAMLESS_CREATE_MODAL;
            // handle always on top
            if (exstyle & WS_EX_TOPMOST)
                flags |= SEAMLESS_CREATE_TOPMOST;

            vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x",
                           hwnd_to_long(hwnd), (long) pid,
                           hwnd_to_long(get_parent(hwnd)), flags);

            GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));

            vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd,
                           vchannel_strfilter_unicode(title), 0);

            icon = get_icon(hwnd, 1);
            if (icon) {
                update_icon(hwnd, icon, 1);
                DeleteObject(icon);
            }

            icon = get_icon(hwnd, 0);
            if (icon) {
                update_icon(hwnd, icon, 0);
                DeleteObject(icon);
            }

            if (style & WS_MAXIMIZE)
                state = 2;
            else if (style & WS_MINIMIZE)
                state = 1;
            else
                state = 0;

            update_position(hwnd);

            vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd,
                           state, 0);
        }

        if (wp->flags & SWP_HIDEWINDOW)
            vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0);

        if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
            break;

        if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
            update_position(hwnd);

        break;
    }

    case WM_SETICON:
        if (!(style & WS_VISIBLE))
            break;

        switch (wparam) {
        case ICON_BIG:
            if (lparam)
                update_icon(hwnd, (HICON) lparam, 1);
            else
                vchannel_write("DELICON", "0x%08lx,RGBA,32,32", hwnd);
            break;
        case ICON_SMALL:
        case 2:
            if (lparam)
                update_icon(hwnd, (HICON) lparam, 0);
            else
                vchannel_write("DELICON", "0x%08lx,RGBA,16,16", hwnd);
            break;
        default:
            debug("Weird icon size %d", (int) wparam);
        }

        break;

    case WM_SIZE:
        if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
            break;
        update_position(hwnd);
        break;

    case WM_MOVE:
        if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
            break;
        update_position(hwnd);
        break;

    case WM_DESTROY:
        if (!(style & WS_VISIBLE))
            break;
        vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, 0);
        break;

    default:
        break;
    }

end:
    return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
}
Ejemplo n.º 15
0
void SeamlessChannel_sendDelIcon(HWND hwnd, unsigned int width, unsigned int height) {
	vchannel_write("DELICON", "0x%08lx,RGBA,%u,%u", hwnd, width, height);
}
Ejemplo n.º 16
0
void SeamlessChannel_sendDestroy(HWND hwnd, int flags) {
	vchannel_write("DESTROY", "0x%08lx,0x%08x", hwnd, flags);
}
Ejemplo n.º 17
0
void SeamlessChannel_sendHello(int flags) {
	vchannel_write("HELLO", "0x%08x", flags);
}
Ejemplo n.º 18
0
int WINAPI
WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
{
	int success = 0;
	HANDLE helper = NULL;
	HMODULE hookdll = NULL;
	SYSTEM_INFO si;

	set_hooks_proc_t set_hooks_fn;
	remove_hooks_proc_t remove_hooks_fn;
	get_instance_count_proc_t instance_count_fn;

	int check_counter;

	if (strlen(cmdline) == 0) {
		message("No command line specified.");
		return -1;
	}

	if (vchannel_open()) {
		message("Unable to set up the virtual channel.");
		return -1;
	}


	GetSystemInfo(&si);
	switch (si.wProcessorArchitecture) {
	case PROCESSOR_ARCHITECTURE_INTEL:
		hookdll = LoadLibrary("seamlessrdp32.dll");
		break;
	case PROCESSOR_ARCHITECTURE_AMD64:
		hookdll = LoadLibrary("seamlessrdp64.dll");
		break;
	default:
		message("Unsupported processor architecture.");
		break;

	}

	if (!hookdll) {
		message("Could not load hook DLL. Unable to continue.");
		goto close_vchannel;
	}

	set_hooks_fn = (set_hooks_proc_t) GetProcAddress(hookdll, "SetHooks");
	remove_hooks_fn =
		(remove_hooks_proc_t) GetProcAddress(hookdll, "RemoveHooks");
	instance_count_fn =
		(get_instance_count_proc_t) GetProcAddress(hookdll, "GetInstanceCount");
	g_move_window_fn =
		(move_window_proc_t) GetProcAddress(hookdll, "SafeMoveWindow");
	g_zchange_fn = (zchange_proc_t) GetProcAddress(hookdll, "SafeZChange");
	g_focus_fn = (focus_proc_t) GetProcAddress(hookdll, "SafeFocus");
	g_set_state_fn = (set_state_proc_t) GetProcAddress(hookdll, "SafeSetState");

	if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn
		|| !g_move_window_fn || !g_zchange_fn || !g_focus_fn
		|| !g_set_state_fn) {
		message
			("Hook DLL doesn't contain the correct functions. Unable to continue.");
		goto close_hookdll;
	}

	/* Check if the DLL is already loaded */
	switch (instance_count_fn()) {
	case 0:
		message("Hook DLL failed to initialize.");
		goto close_hookdll;
		break;
	case 1:
		break;
	default:
		message("Another running instance of Seamless RDP detected.");
		goto close_hookdll;
	}

	helper = launch_helper();

	ProcessIdToSessionId(GetCurrentProcessId(), &g_session_id);

	build_startup_procs();

	g_connected = is_connected();
	g_desktop_hidden = is_desktop_hidden();

	vchannel_write("HELLO", "0x%08x",
		g_desktop_hidden ? SEAMLESS_HELLO_HIDDEN : 0);

	set_hooks_fn();

	/* Since we don't see the entire desktop we must resize windows
	   immediatly. */
	SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);

	/* Disable screen saver since we cannot catch its windows. */
	SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);

	/* We don't want windows denying requests to activate windows. */
	SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0);

	if (!launch_app(cmdline)) {
		// CreateProcess failed.
		char msg[256];
		_snprintf(msg, sizeof(msg),
			"Unable to launch the requested application:\n%s", cmdline);
		message(msg);
		goto unhook;
	}

	check_counter = 5;
	while (check_counter-- || !should_terminate()) {
		BOOL connected;
		MSG msg;

		connected = is_connected();
		if (connected && !g_connected) {
			int flags;
			/* These get reset on each reconnect */
			SystemParametersInfo(SPI_SETDRAGFULLWINDOWS, TRUE, NULL, 0);
			SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
			SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, 0, 0);

			flags = SEAMLESS_HELLO_RECONNECT;
			if (g_desktop_hidden)
				flags |= SEAMLESS_HELLO_HIDDEN;
			vchannel_write("HELLO", "0x%08x", flags);
		}

		g_connected = connected;

		if (check_counter < 0) {
			BOOL hidden;

			hidden = is_desktop_hidden();
			if (hidden && !g_desktop_hidden)
				vchannel_write("HIDE", "0x%08x", 0);
			else if (!hidden && g_desktop_hidden)
				vchannel_write("UNHIDE", "0x%08x", 0);

			g_desktop_hidden = hidden;

			check_counter = 5;
		}

		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		process_cmds();
		Sleep(100);
	}

	success = 1;

  unhook:
	remove_hooks_fn();

	free_startup_procs();
	if (helper) {
		// Terminate seamlessrdphook32.exe
		kill_15_9(helper, "SeamlessRDPHook", HELPER_TIMEOUT);
	}

  close_hookdll:
	FreeLibrary(hookdll);

  close_vchannel:
	vchannel_close();

	// Logoff the user. This is necessary because the session may
	// have started processes that are not included in Microsofts
	// list of processes to ignore. Typically ieuser.exe.
	// FIXME: Only do this if WTSQuerySessionInformation indicates
	// that we are the initial program. 
	ExitWindows(0, 0);

	if (success)
		return 1;
	else
		return -1;
}
Ejemplo n.º 19
0
static void create_window(HWND hwnd){
		unsigned short *title;
		DWORD pid;
		int flags;
		HICON icon;
		LONG exstyle;
		LONG style;
		HWND parent;
		node* window;
		TCHAR classname[256];

		window = getWindowFromHistory(hwnd);
		if (window != NULL) {
			if (window->is_shown)
				return;
		}
		else {
			window = addHWDNToHistory(hwnd);
			if (window == NULL)
				return;
		}

		window->is_shown = TRUE;

		style = GetWindowLong(hwnd, GWL_STYLE);
		vchannel_write("DEBUG","NEW WINDOWS");

		exstyle = GetWindowLong(hwnd, GWL_EXSTYLE);
		GetWindowThreadProcessId(hwnd, &pid);

		parent = get_parent(hwnd);
		if (getWindowFromHistory(parent) == NULL)
			parent = 0;

		flags = 0;
		if (style & DS_MODALFRAME || exstyle & WS_EX_DLGMODALFRAME)
			flags |= SEAMLESS_CREATE_MODAL;

		if (((style & WS_POPUP) || (exstyle & WS_EX_TOOLWINDOW))
			&& (style & WS_MINIMIZEBOX) == 0 && (style & WS_MAXIMIZEBOX) == 0) {
			flags |= SEAMLESS_CREATE_POPUP;
			if (! parent)
				parent = 0xffffffffL;

			if (GetClassName(hwnd, classname, 256)) {
				if ((strcmp(classname, TOOLTIPS_CLASS) == 0)
					|| (strcmp(classname, "Net UI Tool Window") == 0)
					|| (strcmp(classname, "OfficeTooltip") == 0)
					|| (strcmp(classname, "DUIListViewHost") == 0)) {
					debug("%s", classname);
					flags |= SEAMLESS_CREATE_TOOLTIP;
					parent = 0xffffffffL;
				}
				else
					debug("Unknown classname: %s style: 0x%08lx exstyle: 0x%08lx", classname, style, exstyle);
			}
		}
		if (! (style & WS_SIZEBOX))
			flags |= SEAMLESS_CREATE_FIXEDSIZE;

		// handle always on top
		if (exstyle & WS_EX_TOPMOST)
			flags |= SEAMLESS_CREATE_TOPMOST;

		vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x",
					   (long) hwnd, (long) pid, (long) parent, flags);

		title = malloc(sizeof(unsigned short) * TITLE_SIZE);
		if (title != NULL) {
			GetWindowTextW(hwnd, title, TITLE_SIZE);

			vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), 0);
		}
		if (window->title) {
			free(window->title);
			window->title = NULL;
		}
		window->title = title;

		icon = get_icon(hwnd, 1);
		if (icon)
		{
			update_icon(hwnd, icon, 1);
			DeleteObject(icon);
		}

		icon = get_icon(hwnd, 0);
		if (icon)
		{
			update_icon(hwnd, icon, 0);
			DeleteObject(icon);
		}

		if (style & WS_MAXIMIZE)
			window->state = 2;
		else if (style & WS_MINIMIZE)
			window->state = 1;
		else
			window->state = 0;

		update_position(hwnd);
		vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd,
				   window->state, 0);

		if (window->focus)
			vchannel_write("FOCUS", "0x%08lx", hwnd);
}
Ejemplo n.º 20
0
void SeamlessChannel_sendSyncBegin() {
	vchannel_write("SYNCBEGIN", "0x0");
}
Ejemplo n.º 21
0
void SeamlessChannel_sendAppId(unsigned int token, int pid) {
	vchannel_write("APP_ID", "0x%08x,0x%08x", token, pid);
}
Ejemplo n.º 22
0
void SeamlessChannel_sendUnhide(int flags) {
	vchannel_write("UNHIDE", "0x%08x", flags);
}
Ejemplo n.º 23
0
void SeamlessChannel_sendSetIcon(HWND hwnd, int chunk, unsigned int width, unsigned int height, char *buf) {
	vchannel_write("SETICON", "0x%08lx,%d,RGBA,%d,%d,%s", hwnd, chunk, width, height, buf);
}
Ejemplo n.º 24
0
void SeamlessChannel_sendDestroyGrp(unsigned long pid, int flags) {
	vchannel_write("DESTROYGRP", "0x%08lx, 0x%08lx", pid, flags);
}
Ejemplo n.º 25
0
void SeamlessChannel_sendPosition(HWND hwnd, int x, int y, unsigned int width, unsigned int height, int flags) {
	vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x", hwnd, x, y, width, height, flags);
}
Ejemplo n.º 26
0
static LRESULT CALLBACK
wndproc_hook_proc(int code, WPARAM cur_thread, LPARAM details)
{
	HWND hwnd;
	UINT msg;
	WPARAM wparam;
	LPARAM lparam;

	LONG style;

	if (code < 0)
		goto end;

	hwnd = ((CWPSTRUCT *) details)->hwnd;
	msg = ((CWPSTRUCT *) details)->message;
	wparam = ((CWPSTRUCT *) details)->wParam;
	lparam = ((CWPSTRUCT *) details)->lParam;
	
	if (!is_toplevel(hwnd) || is_seamless_internal_windows(hwnd))
	{
		goto end;
	}

	style = GetWindowLong(hwnd, GWL_STYLE);

	switch (msg)
	{
		case WM_SHOWWINDOW:
			{
				create_window(hwnd);
				break;
			}
		case WM_WINDOWPOSCHANGED:
			{
				WINDOWPOS *wp = (WINDOWPOS *) lparam;

				if (wp->flags & SWP_SHOWWINDOW)
				{
					create_window(hwnd);
				}

				if (wp->flags & SWP_HIDEWINDOW)
					destroy_window(hwnd);

				if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
					break;

				if (!(wp->flags & SWP_NOMOVE && wp->flags & SWP_NOSIZE))
					update_position(hwnd);

				break;
			}

		case WM_SETICON:
			if (!(style & WS_VISIBLE))
				break;

			switch (wparam)
			{
				case ICON_BIG:
					if (lparam)
						update_icon(hwnd, (HICON) lparam, 1);
					else
						vchannel_write("DELICON", "0x%08lx,RGBA,32,32",
							       hwnd);
					break;
				case ICON_SMALL:
				case 2:
					if (lparam)
						update_icon(hwnd, (HICON) lparam, 0);
					else
						vchannel_write("DELICON", "0x%08lx,RGBA,16,16",
							       hwnd);
					break;
				default:
					debug("Weird icon size %d", (int) wparam);
			}

			break;

		case WM_SIZE:
			{
				HWND blocked_hwnd;
				int blocked;
				unsigned int serial;
				node* sw;
				int state;
				
				sw = getWindowFromHistory(hwnd);
				if (! sw)
					break;

				WaitForSingleObject(g_mutex, INFINITE);
				blocked_hwnd = g_blocked_state_hwnd;
				serial = g_blocked_state_serial;
				blocked = g_blocked_state;
				ReleaseMutex(g_mutex);

				switch (wparam) {
					case SIZE_MAXIMIZED:
						state = 2;
						break;
					case SIZE_MINIMIZED:
						state = 1;
						break;
					case SIZE_RESTORED:
						state = 0;
						break;
				}

				if (sw->state == state) {
					break;
				}

				sw->state = state;
				if ((blocked_hwnd == hwnd) && (blocked == state)) {
					vchannel_write("ACK", "%u", serial);
				}
				else {
					vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x",
						  hwnd, sw->state, 0);
				}
			}

			if (wparam == SIZE_MAXIMIZED || !(style & WS_VISIBLE) || (style & WS_MINIMIZE))
				break;
			update_position(hwnd);
			break;

		case WM_MOVE:
			if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
				break;
			update_position(hwnd);
			break;

		case WM_DESTROY:
			if (!(style & WS_VISIBLE))
				break;
			destroy_window(hwnd);
			break;

		default:
			break;
	}

      end:
	return CallNextHookEx(g_wndproc_hook, code, cur_thread, details);
}
Ejemplo n.º 27
0
BOOL APIENTRY
DllMain(HINSTANCE hinstDLL, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    HANDLE filemapping = NULL;
    switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
        // remember our instance handle
        g_instance = hinstDLL;

        g_mutex = CreateMutex(NULL, FALSE, "Local\\SeamlessDLL");

        filemapping = CreateFileMapping(INVALID_HANDLE_VALUE,
                                        NULL,
                                        PAGE_READWRITE,
                                        0, sizeof(shared_variables), "Local\\SeamlessRDPData");

        if (filemapping) {
            /* From MSDN: The initial contents of
               the pages in a file mapping object
               backed by the paging file are 0
               (zero)." */
            g_shdata = MapViewOfFile(filemapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
        }

        if (g_mutex && filemapping && g_shdata && vchannel_open() == 0) {
            WaitForSingleObject(g_mutex, INFINITE);
            ++g_shdata->instance_count;
            ReleaseMutex(g_mutex);
            g_wm_seamless_focus = RegisterWindowMessage(FOCUS_MSG_NAME);
        }
        break;

    case DLL_THREAD_ATTACH:
        break;

    case DLL_THREAD_DETACH:
        break;

    case DLL_PROCESS_DETACH:
        if (vchannel_is_open()) {
            vchannel_write("DESTROYGRP", "0x%08lx, 0x%08lx",
                           GetCurrentProcessId(), 0);
            vchannel_close();
        }

        if (g_mutex) {
            WaitForSingleObject(g_mutex, INFINITE);
            if (g_shdata) {
                --g_shdata->instance_count;
                UnmapViewOfFile(g_shdata);
            }
            ReleaseMutex(g_mutex);
            CloseHandle(g_mutex);
        }

        if (filemapping) {
            CloseHandle(filemapping);
        }
        break;
    }

    return TRUE;
}
Ejemplo n.º 28
0
static LRESULT CALLBACK
wndprocret_hook_proc(int code, WPARAM cur_thread, LPARAM details)
{
	HWND hwnd;
	UINT msg;
	WPARAM wparam;
	LPARAM lparam;

	LONG style;

	if (code < 0)
		goto end;

	hwnd = ((CWPRETSTRUCT *) details)->hwnd;
	msg = ((CWPRETSTRUCT *) details)->message;
	wparam = ((CWPRETSTRUCT *) details)->wParam;
	lparam = ((CWPRETSTRUCT *) details)->lParam;

	if (!is_toplevel(hwnd) || is_seamless_internal_windows(hwnd))
	{
		goto end;
	}

	style = GetWindowLong(hwnd, GWL_STYLE);

	switch (msg)
	{
		case WM_WINDOWPOSCHANGED:
			{
				WINDOWPOS *wp = (WINDOWPOS *) lparam;

				if (!(style & WS_VISIBLE) || (style & WS_MINIMIZE))
					break;

				if (!(wp->flags & SWP_NOZORDER))
					//update_zorder(hwnd) --> WinDev applications bring if we do that;
					break;

				break;
			}


		case WM_SETTEXT:
			{
				if (!(style & WS_VISIBLE))
					break;
				/* We cannot use the string in lparam because
				   we need unicode. */
				if (getWindowFromHistory(hwnd) == NULL){
					create_window(hwnd);
				}
				else{
					BOOLEAN titleIsTheSame = TRUE;
					int i = 0;
					unsigned short *title;
					node* window = getWindowFromHistory(hwnd);
					if (window == NULL) {
						break;
					}

					title = malloc(sizeof(unsigned short) * TITLE_SIZE);
					if (title == NULL)
						break;

					GetWindowTextW(hwnd, title, TITLE_SIZE);

					if (window->title != NULL) {
						for (i = 0; i < TITLE_SIZE; i++) {
							if (title[i] != window->title[i]) {
								titleIsTheSame = FALSE;
								break;
							}
						}
					}
					else {
						titleIsTheSame = FALSE;
					}

					if (titleIsTheSame) {
						free(title);
						break;
					}

					vchannel_write("TITLE", "0x%08lx,%s,0x%08x", hwnd, vchannel_strfilter_unicode(title), 0);

					if (window->title) {
						free(window->title);
						window->title;
					}
					window->title = title;
				}
				break;
			}

		case WM_SETICON:
			{
				HICON icon;

				/*
				 * Somehow, we never get WM_SETICON for the small icon.
				 * So trigger a read of it every time the large one is
				 * changed.
				 */
				icon = get_icon(hwnd, 0);
				if (icon)
				{
					update_icon(hwnd, icon, 0);
					DeleteObject(icon);
				}
				break;
			}

		case WM_ACTIVATE:
			// http://msdn.microsoft.com/en-us/library/ms646274(VS.85).aspx
			if (wparam == 0)  // WA_INACTIVE
				break;

		case WM_SETFOCUS: // Focus gained
			if (hwnd == g_last_focused_window)
				break;

			WaitForSingleObject(g_mutex, INFINITE);
			g_last_focused_window = hwnd;
			ReleaseMutex(g_mutex);

			{
				node* window;

				window = getWindowFromHistory(hwnd);
				if (window == NULL) {
					window = addHWDNToHistory(hwnd);
					if (window == NULL)
						goto end;

					window->focus = TRUE;
					goto end;
				}
			}

			vchannel_block();
			vchannel_write("FOCUS", "0x%08lx", hwnd);
			vchannel_unblock();

			break;

		default:
			break;
	}

      end:
	return CallNextHookEx(g_wndprocret_hook, code, cur_thread, details);
}
Ejemplo n.º 29
0
static BOOL CALLBACK
enum_cb(HWND hwnd, LPARAM lparam)
{
	RECT rect;
	unsigned short title[150];
	LONG styles;
	int state;
	HWND parent;
	DWORD pid;
	int flags;
	char classname[32];

	styles = GetWindowLong(hwnd, GWL_STYLE);

	if (!(styles & WS_VISIBLE))
		return TRUE;

	/* Since WH_CALLWNDPROC is not effective on cmd.exe, make sure
	   we ignore it during enumeration as well. Make sure to
	   remove this when cmd.exe support has been added, though. */

	if (GetClassName(hwnd, classname, sizeof(classname))
		&& !strcmp(classname, "ConsoleWindowClass"))
		return TRUE;

	if (styles & WS_POPUP)
		parent = (HWND) GetWindowLongPtr(hwnd, GWLP_HWNDPARENT);
	else
		parent = NULL;

	GetWindowThreadProcessId(hwnd, &pid);

	flags = 0;
	if (styles & DS_MODALFRAME)
		flags |= SEAMLESS_CREATE_MODAL;

	vchannel_write("CREATE", "0x%08lx,0x%08lx,0x%08lx,0x%08x",
		hwnd_to_long(hwnd), (long) pid, hwnd_to_long(parent), flags);

	if (!GetWindowRect(hwnd, &rect)) {
		debug("GetWindowRect failed!");
		return TRUE;
	}

	vchannel_write("POSITION", "0x%08lx,%d,%d,%d,%d,0x%08x",
		hwnd,
		rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);

	GetWindowTextW(hwnd, title, sizeof(title) / sizeof(*title));

	vchannel_write("TITLE", "0x%x,%s,0x%x", hwnd,
		vchannel_strfilter_unicode(title), 0);

	if (styles & WS_MAXIMIZE)
		state = 2;
	else if (styles & WS_MINIMIZE)
		state = 1;
	else
		state = 0;

	vchannel_write("STATE", "0x%08lx,0x%08x,0x%08x", hwnd, state, 0);

	return TRUE;
}
Ejemplo n.º 30
0
void SeamlessChannel_sendSyncEnd() {
	vchannel_write("SYNCEND", "0x0");
}