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

📄 vncservice.cpp

📁 realvnc是一个非常流行的远程控制程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//  Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.//  Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.////  This file is part of the VNC system.////  The VNC system is free software; you can redistribute it and/or modify//  it under the terms of the GNU General Public License as published by//  the Free Software Foundation; either version 2 of the License, or//  (at your option) any later version.////  This program is distributed in the hope that it will be useful,//  but WITHOUT ANY WARRANTY; without even the implied warranty of//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the//  GNU General Public License for more details.////  You should have received a copy of the GNU General Public License//  along with this program; if not, write to the Free Software//  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,//  USA.//// If the source code for the VNC system is not available from the place // whence you received this file, check http://www.uk.research.att.com/vnc or contact// the authors on vnc@uk.research.att.com for information on obtaining it.// vncService// Implementation of service-oriented functionality of WinVNC#include "stdhdrs.h"// Header#include "vncService.h"#include <lmcons.h>#include "omnithread.h"#include "WinVNC.h"#include "vncMenu.h"#include "vncTimedMsgBox.h"// Error message loggingvoid LogErrorMsg(char *message);// OS-SPECIFIC ROUTINES// Create an instance of the vncService class to cause the static fields to be// initialised properlyvncService init;DWORD	g_platform_id;BOOL	g_impersonating_user = 0;DWORD	g_version_major;DWORD	g_version_minor;vncService::vncService(){    OSVERSIONINFO osversioninfo;    osversioninfo.dwOSVersionInfoSize = sizeof(osversioninfo);    // Get the current OS version    if (!GetVersionEx(&osversioninfo))	    g_platform_id = 0;    g_platform_id = osversioninfo.dwPlatformId;	g_version_major = osversioninfo.dwMajorVersion;	g_version_minor = osversioninfo.dwMinorVersion;}// CurrentUser - fills a buffer with the name of the current user!BOOLGetCurrentUser(char *buffer, UINT size){	// How to obtain the name of the current user depends upon the OS being used	if ((g_platform_id == VER_PLATFORM_WIN32_NT) && vncService::RunningAsService())	{		// Windows NT, service-mode		// -=- FIRSTLY - verify that a user is logged on		// Get the current Window station		HWINSTA station = GetProcessWindowStation();		if (station == NULL)			return FALSE;		// Get the current user SID size		DWORD usersize;		GetUserObjectInformation(station,			UOI_USER_SID, NULL, 0, &usersize);		// Check the required buffer size isn't zero		if (usersize == 0)		{			// No user is logged in - ensure we're not impersonating anyone			RevertToSelf();			g_impersonating_user = FALSE;			// Return "" as the name...			if (strlen("") >= size)				return FALSE;			strcpy(buffer, "");			return TRUE;		}		// -=- SECONDLY - a user is logged on but if we're not impersonating		//     them then we can't continue!		if (!g_impersonating_user) {			// Return "" as the name...			if (strlen("") >= size)				return FALSE;			strcpy(buffer, "");			return TRUE;		}	}			// -=- When we reach here, we're either running under Win9x, or we're running	//     under NT as an application or as a service impersonating a user	// Either way, we should find a suitable user name.	switch (g_platform_id)	{	case VER_PLATFORM_WIN32_WINDOWS:	case VER_PLATFORM_WIN32_NT:		{			// Just call GetCurrentUser			DWORD length = size;			if (GetUserName(buffer, &length) == 0)			{				UINT error = GetLastError();				if (error == ERROR_NOT_LOGGED_ON)				{					// No user logged on					if (strlen("") >= size)						return FALSE;					strcpy(buffer, "");					return TRUE;				}				else				{					// Genuine error...					vnclog.Print(LL_INTERR, VNCLOG("getusername error %d\n"), GetLastError());					return FALSE;				}			}		}		return TRUE;	};	// OS was not recognised!	return FALSE;}BOOLvncService::CurrentUser(char *buffer, UINT size){  BOOL result = GetCurrentUser(buffer, size);  if (result && (strcmp(buffer, "") == 0) && !vncService::RunningAsService()) {    strncpy(buffer, "Default", size);  }  return result;}// IsWin95 - returns a BOOL indicating whether the current OS is Win95BOOLvncService::IsWin95(){	return (g_platform_id == VER_PLATFORM_WIN32_WINDOWS);}// IsWinNT - returns a bool indicating whether the current OS is WinNTBOOLvncService::IsWinNT(){	return (g_platform_id == VER_PLATFORM_WIN32_NT);}// Version infoDWORDvncService::VersionMajor(){	return g_version_major;}DWORDvncService::VersionMinor(){	return g_version_minor;}// Internal routine to find the WinVNC menu class window and// post a message to it!BOOLPostToWinVNC(UINT message, WPARAM wParam, LPARAM lParam){	// Locate the hidden WinVNC menu window	HWND hservwnd = FindWindow(MENU_CLASS_NAME, NULL);	if (hservwnd == NULL)		return FALSE;	// Post the message to WinVNC	PostMessage(hservwnd, message, wParam, lParam);	return TRUE;}// Static routines only used on Windows NT to ensure we're in the right desktop// These routines are generally available to any thread at any time.// - SelectDesktop(HDESK)// Switches the current thread into a different desktop by deskto handle// This call takes care of all the evil memory management involvedBOOLvncService::SelectHDESK(HDESK new_desktop){	// Are we running on NT?	if (IsWinNT())	{		HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId());		DWORD dummy;		char new_name[256];		if (!GetUserObjectInformation(new_desktop, UOI_NAME, &new_name, 256, &dummy)) {			return FALSE;		}		vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK to %s (%x) from %x\n"), new_name, new_desktop, old_desktop);		// Switch the desktop		if(!SetThreadDesktop(new_desktop)) {      vnclog.Print(LL_INTERR, VNCLOG("unable to SetThreadDesktop\n"), GetLastError());			return FALSE;		}		// Switched successfully - destroy the old desktop		if (!CloseDesktop(old_desktop))			vnclog.Print(LL_INTERR, VNCLOG("SelectHDESK failed to close old desktop %x (Err=%d)\n"), old_desktop, GetLastError());		return TRUE;	}	return TRUE;}// - SelectDesktop(char *)// Switches the current thread into a different desktop, by name// Calling with a valid desktop name will place the thread in that desktop.// Calling with a NULL name will place the thread in the current input desktop.BOOLvncService::SelectDesktop(char *name){	// Are we running on NT?	if (IsWinNT())	{		HDESK desktop;		if (name != NULL)		{			// Attempt to open the named desktop			desktop = OpenDesktop(name, 0, FALSE,				DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |				DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |				DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |				DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);		}		else		{			// No, so open the input desktop			desktop = OpenInputDesktop(0, FALSE,				DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |				DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |				DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |				DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);		}		// Did we succeed?		if (desktop == NULL) {      vnclog.Print(LL_INTERR, VNCLOG("unable to open desktop:%d\n"), GetLastError());			return FALSE;		}		// Switch to the new desktop		if (!SelectHDESK(desktop)) {			// Failed to enter the new desktop, so free it!			if (!CloseDesktop(desktop))				vnclog.Print(LL_INTERR, VNCLOG("SelectDesktop failed to close desktop:%d\n"), GetLastError());			return FALSE;		}		// We successfully switched desktops!		return TRUE;	}	return (name == NULL);}// Find the visible window station and switch to it// This would allow the service to be started non-interactive// Needs more supporting code & a redesign of the server core to// work, with better partitioning between server & UI components.static HWINSTA home_window_station = GetProcessWindowStation();BOOL CALLBACK WinStationEnumProc(LPTSTR name, LPARAM param) {	HWINSTA station = OpenWindowStation(name, FALSE, GENERIC_ALL);	HWINSTA oldstation = GetProcessWindowStation();	USEROBJECTFLAGS flags;	if (!GetUserObjectInformation(station, UOI_FLAGS, &flags, sizeof(flags), NULL)) {		return TRUE;	}	BOOL visible = flags.dwFlags & WSF_VISIBLE;	if (visible) {		if (SetProcessWindowStation(station)) {			if (oldstation != home_window_station) {				CloseWindowStation(oldstation);			}		} else {			CloseWindowStation(station);		}		return FALSE;	}	return TRUE;}BOOLvncService::SelectInputWinStation(){	home_window_station = GetProcessWindowStation();	return EnumWindowStations(&WinStationEnumProc, NULL);}voidvncService::SelectHomeWinStation(){	HWINSTA station=GetProcessWindowStation();	SetProcessWindowStation(home_window_station);	CloseWindowStation(station);}// NT only function to establish whether we're on the current input desktopBOOLvncService::InputDesktopSelected(){	// Are we running on NT?	if (IsWinNT())	{		// Get the input and thread desktops		HDESK threaddesktop = GetThreadDesktop(GetCurrentThreadId());		HDESK inputdesktop = OpenInputDesktop(0, FALSE,				DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW |				DESKTOP_ENUMERATE | DESKTOP_HOOKCONTROL |				DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS |				DESKTOP_SWITCHDESKTOP | GENERIC_WRITE);		// Get the desktop names:		// *** I think this is horribly inefficient but I'm not sure.		if (inputdesktop == NULL)		    return FALSE;		DWORD dummy;		char threadname[256];		char inputname[256];		if (!GetUserObjectInformation(threaddesktop, UOI_NAME, &threadname, 256, &dummy)) {			if (!CloseDesktop(inputdesktop))				vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n"));			return FALSE;		}		_ASSERT(dummy <= 256);		if (!GetUserObjectInformation(inputdesktop, UOI_NAME, &inputname, 256, &dummy)) {			if (!CloseDesktop(inputdesktop))				vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n"));			return FALSE;		}		_ASSERT(dummy <= 256);		if (!CloseDesktop(inputdesktop))			vnclog.Print(LL_INTWARN, VNCLOG("failed to close input desktop\n"));		if (strcmp(threadname, inputname) != 0)			return FALSE;	}	return TRUE;}// Static routine used to fool Winlogon into thinking CtrlAltDel was pressedvoid *SimulateCtrlAltDelThreadFn(void *context){	HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId());	// Switch into the Winlogon desktop	if (!vncService::SelectDesktop("Winlogon"))	{		vnclog.Print(LL_INTERR, VNCLOG("failed to select logon desktop\n"));		return FALSE;	}	vnclog.Print(LL_ALL, VNCLOG("generating ctrl-alt-del\n"));	// Fake a hotkey event to any windows we find there.... :(	// Winlogon uses hotkeys to trap Ctrl-Alt-Del...	PostMessage(HWND_BROADCAST, WM_HOTKEY, 0, MAKELONG(MOD_ALT | MOD_CONTROL, VK_DELETE));	// Switch back to our original desktop	if (old_desktop != NULL)		vncService::SelectHDESK(old_desktop);	return NULL;}

⌨️ 快捷键说明

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