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; }
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; }