vncservice.cpp

来自「这是一个比较复杂的远程控制工具,分为服务器与客户斋,让你了解socket编程的知」· C++ 代码 · 共 1,359 行 · 第 1/3 页

CPP
1,359
字号
	// 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 ROUTINE
int
vncService::ReinstallService() {
  RemoveService(1);
  Sleep(1000);
  InstallService(1);
  return 0;
}


int
vncService::InstallService(BOOL silent)
{
	const int pathlength = 2048;
	char path[pathlength];
	char servicecmd[pathlength];

	// Get the filename of this executable
  if (GetModuleFileName(NULL, path, pathlength-(strlen(winvncRunService)+2)) == 0) {
    if (!silent) {
		  MessageBox(NULL, sz_ID_UNABLE_INST, szAppName, MB_ICONEXCLAMATION | MB_OK);
    }
    return 0;
  }

	// Append the service-start flag to the end of the path:
	if (strlen(path) + 4 + strlen(winvncRunService) < pathlength)
		sprintf(servicecmd, "\"%s\" %s", path, winvncRunService);
	else
		return 0;

	// How to add the WinVNC service depends upon the OS
	switch (g_platform_id)
	{

		// Windows 95/98
	case VER_PLATFORM_WIN32_WINDOWS:
		{
			// Locate the RunService registry entry
			HKEY runservices;
			if (RegCreateKey(HKEY_LOCAL_MACHINE, 
				"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
				&runservices) != ERROR_SUCCESS)
			{
        if (!silent) {
				  MessageBox(NULL, sz_ID_SCM_NOT_HERE, szAppName, MB_ICONEXCLAMATION | MB_OK);
        }
        break;
			}

			// Attempt to add a WinVNC key
			if (RegSetValueEx(runservices, szAppName, 0, REG_SZ, (unsigned char *)servicecmd, strlen(servicecmd)+1) != ERROR_SUCCESS)
			{
				RegCloseKey(runservices);
        if (!silent) {
				  MessageBox(NULL, sz_ID_SERV_NOT_REG, szAppName, MB_ICONEXCLAMATION | MB_OK);
        }
				break;
			}

			RegCloseKey(runservices);

			// We have successfully installed the service!

			if (!silent)vncTimedMsgBox::Do(
				sz_ID_SERV_SUCCESS_INST,
				szAppName,
				MB_ICONINFORMATION | MB_OK);


			// Run the service...
			STARTUPINFO si;
			si.cb = sizeof(si);
			si.cbReserved2 = 0;
			si.lpReserved = NULL;
			si.lpReserved2 = NULL;
			si.dwFlags = 0;
			si.lpTitle = NULL;
			PROCESS_INFORMATION pi;
			if (!CreateProcess(
				NULL, servicecmd,							// Program name & path
				NULL, NULL,									// Security attributes
				FALSE,										// Inherit handles?
				NORMAL_PRIORITY_CLASS,						// Extra startup flags
				NULL,										// Environment table
				NULL,										// Current directory
				&si,
				&pi
				))
			{
        if(!silent) {
				  MessageBox(NULL, sz_ID_SERV_FAIL_ST,
            szAppName, MB_ICONSTOP | MB_OK);
        }
				break;
			}
		}
		break;

		// Windows NT
	case VER_PLATFORM_WIN32_NT:
		{
			SC_HANDLE   hservice;
		  SC_HANDLE   hsrvmanager;

			// Open the default, local Service Control Manager database
		  hsrvmanager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
			if (hsrvmanager == NULL)
			{
        if (!silent) {
				MessageBox(NULL,
					sz_ID_SERV_CT_MISS,
					szAppName,
					MB_ICONEXCLAMATION | MB_OK);
        }
				break;
			}
			// Create an entry for the WinVNC service
			hservice = CreateService(
				hsrvmanager,				// SCManager database
				VNCSERVICENAME,				// name of service
				VNCSERVICEDISPLAYNAME,		// name to display
				SERVICE_ALL_ACCESS,			// desired access
				SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
											// service type
				SERVICE_AUTO_START,			// start type
				SERVICE_ERROR_NORMAL,		// error control type
				servicecmd,					// service's binary
				NULL,						// no load ordering group
				NULL,						// no tag identifier
				VNCDEPENDENCIES,			// dependencies
				NULL,						// LocalSystem account
				NULL);						// no password
			if (hservice == NULL)
			{
				DWORD error = GetLastError();
        if (!silent) {
				  if (error == ERROR_SERVICE_EXISTS) {
					  MessageBox(NULL,
						  sz_ID_SERV_OLD_REG,
						  szAppName,
						  MB_ICONEXCLAMATION | MB_OK);
				  } else {
					  MessageBox(NULL,
						  sz_ID_SERV_NOT_REG,
						  szAppName,
						  MB_ICONEXCLAMATION | MB_OK);
				  }
        }
 				CloseServiceHandle(hsrvmanager);
				break;
			}
			CloseServiceHandle(hsrvmanager);
			CloseServiceHandle(hservice);

			// Now install the servicehelper registry setting...
			// Locate the RunService registry entry
			HKEY runapps;
			if (RegCreateKey(HKEY_LOCAL_MACHINE, 
				"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
				&runapps) != ERROR_SUCCESS)
			{
        if (!silent) {
				  MessageBox(NULL, sz_ID_SERVHELP_UNAB, szAppName, MB_ICONEXCLAMATION | MB_OK);
        }
			} else {
				char servicehelpercmd[pathlength];

				// Append the service-helper-start flag to the end of the path:
				if (strlen(path) + 4 + strlen(winvncRunServiceHelper) < pathlength)
					sprintf(servicehelpercmd, "\"%s\" %s", path, winvncRunServiceHelper);
				else
					return 0;

				// Add the VNCserviceHelper entry
				if (RegSetValueEx(runapps, szAppName, 0, REG_SZ,
					(unsigned char *)servicehelpercmd, strlen(servicehelpercmd)+1) != ERROR_SUCCESS)
				{
          if (!silent) {
					  MessageBox(NULL, sz_ID_SERVHELP_UNAB, szAppName, MB_ICONEXCLAMATION | MB_OK);
          }
        }
				RegCloseKey(runapps);
			}

			// Everything went fine
			if (!silent)vncTimedMsgBox::Do(
				sz_ID_SERV_SUCCESS_REG,
				szAppName,
				MB_ICONINFORMATION | MB_OK);

		}
		break;
	};

	return 0;
}

// SERVICE REMOVE ROUTINE
int
vncService::RemoveService(BOOL silent)
{
	// How to remove the WinVNC service depends upon the OS
	switch (g_platform_id)
	{

		// Windows 95/98
	case VER_PLATFORM_WIN32_WINDOWS:
		{
			// Locate the RunService registry entry
			HKEY runservices;
			if (RegOpenKey(HKEY_LOCAL_MACHINE, 
				"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",
				&runservices) != ERROR_SUCCESS)
			{
        if (!silent) {
				  MessageBox(NULL, sz_ID_SERV_CT_UNREG, szAppName, MB_ICONEXCLAMATION | MB_OK);
			  }
      }
			else
			{
				// Attempt to delete the WinVNC key
				if (RegDeleteValue(runservices, szAppName) != ERROR_SUCCESS)
				{
					RegCloseKey(runservices);
          if (!silent) {
					  MessageBox(NULL, sz_ID_SERV_NOT_UNRG, szAppName, MB_ICONEXCLAMATION | MB_OK);
				  }
        }

				RegCloseKey(runservices);
				break;
			}

			// Try to kill any running copy of WinVNC
			if (!KillRunningCopy())
			{
        if (!silent) {
				  MessageBox(NULL,
					  sz_ID_SERV_NCONTACT,
					  szAppName,
					  MB_ICONEXCLAMATION | MB_OK);
        }
				break;
			}

			// We have successfully removed the service!
			if (!silent) vncTimedMsgBox::Do(sz_ID_SERV_SUCCESS_UNREG, szAppName, MB_ICONINFORMATION | MB_OK);

		}
		break;

		// Windows NT
	case VER_PLATFORM_WIN32_NT:
		{
			SC_HANDLE   hservice;
			SC_HANDLE   hsrvmanager;

			// Attempt to remove the service-helper hook
			HKEY runapps;
			if (RegOpenKey(HKEY_LOCAL_MACHINE, 
				"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
				&runapps) == ERROR_SUCCESS)
			{
				// Attempt to delete the WinVNC key
				if (RegDeleteValue(runapps, szAppName) != ERROR_SUCCESS)
				{
          if (!silent) {
					  MessageBox(NULL, sz_ID_SERVHELP_NREM, szAppName, MB_ICONEXCLAMATION | MB_OK);
          }
        }
				RegCloseKey(runapps);
			}

			// Open the SCM
		    hsrvmanager = OpenSCManager(
                        NULL,                   // machine (NULL == local)
                        NULL,                   // database (NULL == default)
                        SC_MANAGER_ALL_ACCESS   // access required
                        );
		    if (hsrvmanager)
		    {
		        hservice = OpenService(hsrvmanager, VNCSERVICENAME, SERVICE_ALL_ACCESS);

				if (hservice != NULL)
				{
					SERVICE_STATUS status;

					// Try to stop the WinVNC service
					if (ControlService(hservice, SERVICE_CONTROL_STOP, &status))
					{
						while(QueryServiceStatus(hservice, &status))
						{
							if (status.dwCurrentState == SERVICE_STOP_PENDING)
								Sleep(1000);
							else
								break;
						}

            if (status.dwCurrentState != SERVICE_STOPPED) {
              if (!silent) {
							  MessageBox(NULL, sz_ID_SERV_NOT_STOP, szAppName, MB_ICONEXCLAMATION | MB_OK);
              }
            }
          }

					// Now remove the service from the SCM
					if(DeleteService(hservice)) {

						if (!silent) vncTimedMsgBox::Do(sz_ID_SERV_SUCCESS_UNREG, szAppName, MB_ICONINFORMATION | MB_OK);

					} else {
						DWORD error = GetLastError();
						if (error == ERROR_SERVICE_MARKED_FOR_DELETE) {
              if (!silent)
							  MessageBox(NULL, sz_ID_SERV_MK_UNREG, szAppName, MB_ICONEXCLAMATION | MB_OK);
						} else {
              if (!silent)
							  MessageBox(NULL, sz_ID_SERV_NOT_UNRG, szAppName, MB_ICONEXCLAMATION | MB_OK);
						}
					}
					CloseServiceHandle(hservice);
				}
        else if (!silent)
					MessageBox(NULL, sz_ID_SERV_NT_FOUND, szAppName, MB_ICONEXCLAMATION | MB_OK);

				CloseServiceHandle(hsrvmanager);
			}
			else if (!silent)
				MessageBox(NULL, sz_ID_SERV_CT_UNREG, szAppName, MB_ICONEXCLAMATION | MB_OK);
		}
		break;
	};
	return 0;
}

// USEFUL SERVICE SUPPORT ROUTINES

// Service control routine
void WINAPI ServiceCtrl(DWORD ctrlcode)
{
	// What control code have we been sent?
//	Beep(1000,10);
//	vnclog.Print(LL_INTINFO, VNCLOG("ctrlcode %d \n"),ctrlcode);
    switch(ctrlcode)
    {

	case SERVICE_CONTROL_SHUTDOWN:
		g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING;
  //      ServiceStop();
		serviceshutdown=true;
		vnclog.Print(LL_INTERR, VNCLOG("SERVICE_CONTROL_SHUTDOWN\n"));
        break;
	case SERVICE_CONTROL_STOP:
		// STOP : The service must stop
		g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING;
		vnclog.Print(LL_INTERR, VNCLOG("SERVICE_CONTROL_STOP\n"));
        ServiceStop();
        break;

    case SERVICE_CONTROL_INTERROGATE:
		// QUERY : Service control manager just wants to know our state
		break;

	default:
		// Control code not recognised
		break;

    }

	// Tell the control manager what we're up to.
    ReportStatus(g_srvstatus.dwCurrentState, NO_ERROR, 0);
}

// Service manager status reporting
BOOL ReportStatus(DWORD state,
				  DWORD exitcode,
				  DWORD waithint)
{
	static DWORD checkpoint = 1;
	BOOL result = TRUE;

	// If we're in the start state then we don't want the control manager
	// sending us control messages because they'll confuse us.
    if (state == SERVICE_START_PENDING)
		g_srvstatus.dwControlsAccepted = 0;
	else
		g_srvstatus.dwControlsAccepted = SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN;

	// Save the new status we've been given
	g_srvstatus.dwCurrentState = state;
	g_srvstatus.dwWin32ExitCode = exitcode;
	g_srvstatus.dwWaitHint = waithint;

	// Update the checkpoint variable to let the SCM know that we
	// haven't died if requests take a long time
	if ((state == SERVICE_RUNNING) || (state == SERVICE_STOPPED))
		g_srvstatus.dwCheckPoint = 0;
	else
        g_srvstatus.dwCheckPoint = checkpoint++;

	// Tell the SCM our new status
	if (!(result = SetServiceStatus(g_hstatus, &g_srvstatus)))
		LogErrorMsg("SetServiceStatus failed");

    return result;
}

// Error reporting
void LogErrorMsg(char *message)
{
    char	msgbuff[256];
    HANDLE	heventsrc;
    char *	strings[2];

	// Save the error code
	g_error = GetLastError();

	// Use event logging to log the error
    heventsrc = RegisterEventSource(NULL, VNCSERVICENAME);

	_snprintf(msgbuff, 256, "%s error: %d", VNCSERVICENAME, g_error);
    strings[0] = msgbuff;
    strings[1] = message;

	if (heventsrc != NULL)
	{
		MessageBeep(MB_OK);

		ReportEvent(
			heventsrc,				// handle of event source
			EVENTLOG_ERROR_TYPE,	// event type
			0,						// event category
			0,						// event ID
			NULL,					// current user's SID
			2,						// strings in 'strings'
			0,						// no bytes of raw data
			(const char **)strings,	// array of error strings
			NULL);					// no raw data

		DeregisterEventSource(heventsrc);
	}
}

⌨️ 快捷键说明

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