⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vncservice.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// Static routine to simulate Ctrl-Alt-Del locallyBOOLvncService::SimulateCtrlAltDel(){	vnclog.Print(LL_ALL, VNCLOG("preparing to generate ctrl-alt-del\n"));	// Are we running on NT?	if (IsWinNT())	{		vnclog.Print(LL_ALL, VNCLOG("spawn ctrl-alt-del thread...\n"));		// *** This is an unpleasant hack.  Oh dear.		// I simulate CtrAltDel by posting a WM_HOTKEY message to all		// the windows on the Winlogon desktop.		// This requires that the current thread is part of the Winlogon desktop.		// But the current thread has hooks set & a window open, so it can't		// switch desktops, so I instead spawn a new thread & let that do the work...		omni_thread *thread = omni_thread::create(SimulateCtrlAltDelThreadFn);		if (thread == NULL)			return FALSE;		thread->join(NULL);		return TRUE;	}	return TRUE;}// Static routine to lock a 2K or above workstationBOOLvncService::LockWorkstation(){	if (!IsWinNT()) {		vnclog.Print(LL_INTERR, VNCLOG("unable to lock workstation - not NT\n"));		return FALSE;	}	vnclog.Print(LL_ALL, VNCLOG("locking workstation\n"));	// Load the user32 library	HMODULE user32 = LoadLibrary("user32.dll");	if (!user32) {		vnclog.Print(LL_INTERR, VNCLOG("unable to load User32 DLL (%u)\n"), GetLastError());		return FALSE;	}	// Get the LockWorkstation function	typedef BOOL (*LWProc) ();	LWProc lockworkstation = (LWProc)GetProcAddress(user32, "LockWorkStation");	if (!lockworkstation) {		vnclog.Print(LL_INTERR, VNCLOG("unable to locate LockWorkStation - requires Windows 2000 or above (%u)\n"), GetLastError());		FreeLibrary(user32);		return FALSE;	}		// Attempt to lock the workstation	BOOL result = (lockworkstation)();	if (!result) {		vnclog.Print(LL_INTERR, VNCLOG("call to LockWorkstation failed\n"));		FreeLibrary(user32);		return FALSE;	}	FreeLibrary(user32);	return result;}// Static routine to show the Properties dialog for a currently-running// copy of WinVNC, (usually a servicified version.)BOOLvncService::ShowProperties(){	// Post to the WinVNC menu window	if (!PostToWinVNC(MENU_PROPERTIES_SHOW, 0, 0))	{		MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK);		return FALSE;	}	return TRUE;}// Static routine to show the Default Properties dialog for a currently-running// copy of WinVNC, (usually a servicified version.)BOOLvncService::ShowDefaultProperties(){	// Post to the WinVNC menu window	if (!PostToWinVNC(MENU_DEFAULT_PROPERTIES_SHOW, 0, 0))	{		MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK);		return FALSE;	}	return TRUE;}// Static routine to show the About dialog for a currently-running// copy of WinVNC, (usually a servicified version.)BOOLvncService::ShowAboutBox(){	// Post to the WinVNC menu window	if (!PostToWinVNC(MENU_ABOUTBOX_SHOW, 0, 0))	{		MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK);		return FALSE;	}	return TRUE;}// Static routine to tell a locally-running instance of the server// to connect out to a new clientBOOLvncService::PostAddNewClient(unsigned long ipaddress){	// Post to the WinVNC menu window	if (!PostToWinVNC(MENU_ADD_CLIENT_MSG, 0, ipaddress))	{		MessageBox(NULL, "No existing instance of WinVNC could be contacted", szAppName, MB_ICONEXCLAMATION | MB_OK);		return FALSE;	}	return TRUE;}// SERVICE-MODE ROUTINES// Service-mode defines:// Executable name#define VNCAPPNAME            "winvnc"// Internal service name#define VNCSERVICENAME        "winvnc"// Displayed service name#define VNCSERVICEDISPLAYNAME "VNC Server"// List of other required services ("dependency 1\0dependency 2\0\0")// *** These need filling in properly#define VNCDEPENDENCIES       ""// Internal service stateSERVICE_STATUS          g_srvstatus;       // current status of the serviceSERVICE_STATUS_HANDLE   g_hstatus;DWORD                   g_error = 0;DWORD					g_servicethread = NULL;char*                   g_errortext[256];// Forward defines of internal service functionsvoid WINAPI ServiceMain(DWORD argc, char **argv);void ServiceWorkThread(void *arg);void ServiceStop();void WINAPI ServiceCtrl(DWORD ctrlcode);bool WINAPI CtrlHandler (DWORD ctrltype);BOOL ReportStatus(DWORD state, DWORD exitcode, DWORD waithint);// ROUTINE TO QUERY WHETHER THIS PROCESS IS RUNNING AS A SERVICE OR NOTBOOL	g_servicemode = FALSE;BOOLvncService::RunningAsService(){	return g_servicemode;}BOOLvncService::KillRunningCopy(){	// Locate the hidden WinVNC menu window	HWND hservwnd;	while ((hservwnd = FindWindow(MENU_CLASS_NAME, NULL)) != NULL)	{		// Post the message to WinVNC		PostMessage(hservwnd, WM_CLOSE, 0, 0);		omni_thread::sleep(1);	}	return TRUE;}// ROUTINE TO POST THE HANDLE OF THE CURRENT USER TO THE RUNNING WINVNC, IN ORDER// THAT IT CAN LOAD THE APPROPRIATE SETTINGS.  THIS IS USED ONLY BY THE SVCHELPER// OPTION, WHEN RUNNING UNDER NTBOOLvncService::PostUserHelperMessage(){	// - Check the platform type	if (!IsWinNT())		return TRUE;	// - Get the current process ID	DWORD processId = GetCurrentProcessId();	// - Post it to the existing WinVNC  int retries = 6;	while (!PostToWinVNC(MENU_SERVICEHELPER_MSG, 0, (LPARAM)processId) && retries--)    omni_thread::sleep(10);	// - Wait until it's been used	omni_thread::sleep(5);	return retries;}// ROUTINE TO PROCESS AN INCOMING INSTANCE OF THE ABOVE MESSAGEBOOLvncService::ProcessUserHelperMessage(WPARAM wParam, LPARAM lParam) {	// - Check the platform type	if (!IsWinNT() || !vncService::RunningAsService())		return TRUE;	// - Close the HKEY_CURRENT_USER key, to force NT to reload it for the new user	// NB: Note that this is _really_ dodgy if ANY other thread is accessing the key!	if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS) {		vnclog.Print(LL_INTERR, VNCLOG("failed to close current registry hive\n"));		return FALSE;	}	// - Revert to our own identity	RevertToSelf();	g_impersonating_user = FALSE;	// - Open the specified process	HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, (DWORD)lParam);	if (processHandle == NULL) {		vnclog.Print(LL_INTERR, VNCLOG("failed to open specified process(%d)\n"), GetLastError());		return FALSE;	}	// - Get the token for the given process	HANDLE userToken = NULL;	if (!OpenProcessToken(processHandle, TOKEN_QUERY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE, &userToken)) {		vnclog.Print(LL_INTERR, VNCLOG("failed to get user token(%d)\n"), GetLastError());		CloseHandle(processHandle);		return FALSE;	}	CloseHandle(processHandle);	// - Set this thread to impersonate them	if (!ImpersonateLoggedOnUser(userToken)) {		vnclog.Print(LL_INTERR, VNCLOG("failed to impersonate user(%d)\n"), GetLastError());		CloseHandle(userToken);		return FALSE;	}	CloseHandle(userToken);	g_impersonating_user = TRUE;	vnclog.Print(LL_INTINFO, VNCLOG("impersonating logged on user\n"));	return TRUE;}// SERVICE MAIN ROUTINEintvncService::WinVNCServiceMain(){	typedef DWORD (WINAPI * RegisterServiceProc)(DWORD, DWORD);	const ULONG RSP_SIMPLE_SERVICE = 0x00000001;	const ULONG RSP_UNREGISTER_SERVICE = 0x00000000;	g_servicemode = TRUE;	// How to run as a service depends upon the OS being used	switch (g_platform_id)	{		// Windows 95/98	case VER_PLATFORM_WIN32_WINDOWS:		{			// Obtain a handle to the kernel library			HINSTANCE kerneldll = LoadLibrary("KERNEL32.DLL");			if (kerneldll == NULL)				break;			// And find the RegisterServiceProcess function			RegisterServiceProc RegisterService;			RegisterService = (RegisterServiceProc) GetProcAddress(kerneldll, "RegisterServiceProcess");			if (RegisterService == NULL)				break;						// Register this process with the OS as a service!			RegisterService(NULL, RSP_SIMPLE_SERVICE);			// Run the service itself			WinVNCAppMain();			// Then remove the service from the system service table			RegisterService(NULL, RSP_UNREGISTER_SERVICE);			// Free the kernel library			FreeLibrary(kerneldll);			// *** If we don't kill the process directly here, then 			// for some reason, WinVNC crashes...			// *** Is this now fixed (with the stdcall patch above)?			//ExitProcess(0);		}		break;		// Windows NT	case VER_PLATFORM_WIN32_NT:		{			// Create a service entry table			SERVICE_TABLE_ENTRY dispatchTable[] =		    {				{VNCSERVICENAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},				{NULL, NULL}			};			// Call the service control dispatcher with our entry table			if (!StartServiceCtrlDispatcher(dispatchTable))				LogErrorMsg("StartServiceCtrlDispatcher failed.");		}		break;	};	return 0;}// SERVICE MAIN ROUTINEvoid WINAPI ServiceMain(DWORD argc, char**argv){	// Register the service control handler    g_hstatus = RegisterServiceCtrlHandler(VNCSERVICENAME, ServiceCtrl);    if (g_hstatus == 0)		return;	// Set up some standard service state values    g_srvstatus.dwServiceType = SERVICE_WIN32 | SERVICE_INTERACTIVE_PROCESS;    g_srvstatus.dwServiceSpecificExitCode = 0;	// Give this status to the SCM    if (!ReportStatus(        SERVICE_START_PENDING,	// Service state        NO_ERROR,				// Exit code type        15000))					// Hint as to how long WinVNC should have hung before you assume error	{        ReportStatus(			SERVICE_STOPPED,			g_error,            0);		return;	}	// Now start the service for real    omni_thread *workthread = omni_thread::create(ServiceWorkThread);    return;}// SERVICE START ROUTINE - thread that calls WinVNCAppMainvoid ServiceWorkThread(void *arg){	// Save the current thread identifier	g_servicethread = GetCurrentThreadId();    // report the status to the service control manager.    //    if (!ReportStatus(        SERVICE_RUNNING,       // service state        NO_ERROR,              // exit code        0))                    // wait hint		return;	// RUN!	WinVNCAppMain();	// Mark that we're no longer running	g_servicethread = NULL;	// Tell the service manager that we've stopped.    ReportStatus(		SERVICE_STOPPED,		g_error,		0);}// SERVICE STOP ROUTINE - post a quit message to the relevant threadvoid ServiceStop(){	// Post a quit message to the main service thread	if (g_servicethread != NULL)	{		vnclog.Print(LL_INTINFO, VNCLOG("quitting from ServiceStop\n"));		PostThreadMessage(g_servicethread, WM_QUIT, 0, 0);	}}// SERVICE INSTALL ROUTINEintvncService::ReinstallService() {  RemoveService(1);  InstallService(0);  return 0;}intvncService::InstallService(BOOL silent){	const int pathlength = 2048;	char path[pathlength];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -