Esempio n. 1
0
void *thread_vchannel_process (void * arg)
{
	struct stream* s = NULL;
	int rv;
	int length;
	int total_length;

	signal(SIGCHLD, handler);
	cliprdr_send_ready();
	cliprdr_send_capability();

	while(running){
		make_stream(s);
		init_stream(s, 1600);

		rv = vchannel_receive(cliprdr_channel, s->data, &length, &total_length);
		if( rv == ERROR )
		{
			log_message(l_config, LOG_LEVEL_ERROR, "vchannel_cliprdr[thread_vchannel_process]: "
					"Invalid message");
			vchannel_close(cliprdr_channel);
			pthread_exit ((void*)1);
		}
		switch(rv)
		{
		case ERROR:
			log_message(l_config, LOG_LEVEL_ERROR, "vchannel_cliprdr[thread_vchannel_process]: "
					"Invalid message");
			break;
		case STATUS_CONNECTED:
			log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[thread_vchannel_process]: "
					"Status connected");
			break;
		case STATUS_DISCONNECTED:
			log_message(l_config, LOG_LEVEL_DEBUG, "vchannel_cliprdr[thread_vchannel_process]: "
					"Status disconnected");
			running = 0;

			// Send a dummy event in order to unblock XNextEvent function
			send_dummy_event();

			break;
		default:
			if (length == 0)
			{
				running = false;
				send_dummy_event();
				pthread_exit (0);
			}

			cliprdr_process_message(s, length, total_length);
			break;
		}
		free_stream(s);
	}
	pthread_exit (0);
}
Esempio n. 2
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;
}
void SeamlessChannel_uninit() {
	vchannel_close();

	WaitForSingleObject(g_mutex_orders, INFINITE);

	if (g_last_state_order) {
		free(g_last_state_order);
		g_last_state_order = NULL;
	}

	if (g_last_position_order) {
		free(g_last_position_order);
		g_last_position_order = NULL;
	}

	if (g_last_destroy_order) {
		free(g_last_destroy_order);
		g_last_destroy_order = NULL;
	}

	if (g_last_zchange_order) {
		free(g_last_zchange_order);
		g_last_zchange_order = NULL;
	}

	if (g_last_focus_order) {
		free(g_last_focus_order);
		g_last_focus_order = NULL;
	}

	ReleaseMutex(g_mutex_orders);

	CloseHandle(g_mutex_orders);
	g_mutex_orders = NULL;

	WaitForSingleObject(g_mutex_focus, INFINITE);
	ReleaseMutex(g_mutex_focus);
	CloseHandle(g_mutex_focus);
	g_mutex_focus = NULL;
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}