BOOL SeamlessChannel_init() { g_mutex_orders = CreateMutex(NULL, FALSE, NULL); if (! g_mutex_orders) return FALSE; g_mutex_focus = CreateMutex(NULL, FALSE, NULL); if (! g_mutex_orders) return FALSE; vchannel_open(); return TRUE; }
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; }
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; }
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; }
int main(int argc, char** argv, char** environ) { pthread_t Xevent_thread, Vchannel_thread; void *ret; l_config = g_malloc(sizeof(struct log_config), 1); if (cliprdr_init() != LOG_STARTUP_OK) { g_printf("cliprdr[main]: Enable to init log system\n"); g_free(l_config); return 1; } if (vchannel_init() == ERROR) { g_printf("cliprdr[main]: Enable to init channel system\n"); g_free(l_config); return 1; } pthread_cond_init(&reply_cond, NULL); pthread_mutex_init(&mutex, NULL); cliprdr_channel = vchannel_open("cliprdr"); if( cliprdr_channel == ERROR) { log_message(l_config, LOG_LEVEL_ERROR, "cliprdr[main]: " "Error while connecting to vchannel provider"); g_free(l_config); return 1; } XInitThreads(); log_message(l_config, LOG_LEVEL_DEBUG, "cliprdr[main]: " "Opening the default display : %s",getenv("DISPLAY")); if ((display = XOpenDisplay(0))== 0){ log_message(l_config, LOG_LEVEL_ERROR, "cliprdr[main]: " "Unable to open the default display : %s ",getenv("DISPLAY")); g_free(l_config); return 1; } XSynchronize(display, 1); XSetErrorHandler(error_handler); running = 1; if (pthread_create (&Xevent_thread, NULL, thread_Xvent_process, (void*)0) < 0) { log_message(l_config, LOG_LEVEL_ERROR, "cliprdr[main]: " "Pthread_create error for thread : Xevent_thread"); g_free(l_config); return 1; } if (pthread_create (&Vchannel_thread, NULL, thread_vchannel_process, (void*)0) < 0) { log_message(l_config, LOG_LEVEL_ERROR, "cliprdr[main]: " "Pthread_create error for thread : Vchannel_thread"); g_free(l_config); return 1; } (void)pthread_join (Xevent_thread, &ret); //(void)pthread_join (Vchannel_thread, &ret); pthread_mutex_destroy(&mutex); XCloseDisplay(display); g_free(l_config); return 0; }