Ejemplo n.º 1
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.º 2
0
int WINAPI
WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmdline, int cmdshow)
{
	BOOL use_active_monitoring = DEFAULT_USE_ACTIVE_MONITORING;
	HMODULE hookdll;
	MSG msg;
	int check_counter;

	set_hooks_proc_t set_hooks_fn;
	remove_hooks_proc_t remove_hooks_fn;
	get_instance_count_proc_t instance_count_fn;

	g_instance = instance;

	load_configuration(&use_active_monitoring, &g_is_move_offscreen_forbidden);

	if (! use_active_monitoring) {
		hookdll = LoadLibrary("seamlessrdp.dll");
		if (!hookdll)
		{
			message("Could not load hook DLL. Unable to continue.");
			return -1;
		}

		if (IsWow64())
		{
			STARTUPINFO si;
			PROCESS_INFORMATION pi;

			ZeroMemory( &si, sizeof(si) );
			si.cb = sizeof(si);
			ZeroMemory( &pi, sizeof(pi) );

			// Start the child process.
			if (! CreateProcess(NULL, "hook_launcher_x64.exe", NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
				message("CreateProcess failed.\n");
				return -1;
			}
			CloseHandle(pi.hProcess);
			CloseHandle(pi.hThread);
		}

		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");

		if (!set_hooks_fn || !remove_hooks_fn || !instance_count_fn)
		{
			FreeLibrary(hookdll);
			message("Hook DLL doesn't contain the correct functions. Unable to continue.");
			return -1;
		}

		/* Check if the DLL is already loaded */
		if (instance_count_fn() != 1)
		{
			FreeLibrary(hookdll);
			message("Another running instance of Seamless RDP detected.");
			return -1;
		}
	}

	ProcessIdToSessionId(GetCurrentProcessId(), &g_session_id);

	build_startup_procs();

	if (! SeamlessChannel_init())
		return -1;

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

	if (InternalWindow_create(instance, use_active_monitoring ? NULL : InternalWindow_processCopyData) == FALSE)
		SeamlessChannel_sendDebug("Failed to create seamless internal window");

	SeamlessChannel_sendHello(g_desktop_hidden ? SEAMLESS_HELLO_HIDDEN : 0);

	if (use_active_monitoring)
		start_windows_monitoring();
	else
		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);


	check_counter = 5;
	while (1)
	{
		BOOL connected;
		char* line = NULL;
		int size = 0;

		connected = is_connected();
		if (connected && !g_connected)
		{
			int flags;

			// We have to force reopening channel
			SeamlessChannel_uninit();
			SeamlessChannel_init();

			/* 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;
			SeamlessChannel_sendHello(flags);
		}

		g_connected = connected;

		if (check_counter < 0)
		{
			BOOL hidden;

			hidden = is_desktop_hidden();
			if (hidden && !g_desktop_hidden)
				SeamlessChannel_sendHide(0);
			else if (!hidden && g_desktop_hidden)
				SeamlessChannel_sendUnhide(0);

			g_desktop_hidden = hidden;

			check_counter = 5;
		}

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

		while (SeamlessChannel_recv(&line) >= 0) {
			SeamlessChannel_process(line);
		}
		
		Sleep(100);
	}

	if (use_active_monitoring)
		stop_windows_monitoring();
	else {
		remove_hooks_fn();

		FreeLibrary(hookdll);
	}

	SeamlessChannel_uninit();

	free_startup_procs();

	return 1;
}