📄 vncservice.cpp
字号:
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 thread
void 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 ROUTINE
int
vncService::ReinstallService() {
RemoveService(1);
InstallService(0);
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, "Unable to install WinVNC service", 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, "The SCM could not be contacted - the WinVNC service was not installed", 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, "The WinVNC service could not be registered", szAppName, MB_ICONEXCLAMATION | MB_OK);
}
break;
}
RegCloseKey(runservices);
// We have successfully installed the service!
if (!silent) {
vncTimedMsgBox::Do(
"The WinVNC service was successfully installed\n"
"The service will start now and will automatically\n"
"be run the next time this machine is reset",
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, "The WinVNC service failed to start",
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,
"The Service Control Manager could not be contacted - the WinVNC service was not registered",
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,
"The WinVNC service is already registered",
szAppName,
MB_ICONEXCLAMATION | MB_OK);
} else {
MessageBox(NULL,
"The WinVNC service could not be registered",
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, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", 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, "WARNING:Unable to install the ServiceHelper hook\nGlobal user-specific registry settings will not be loaded", szAppName, MB_ICONEXCLAMATION | MB_OK);
}
}
RegCloseKey(runapps);
}
// Everything went fine
if (!silent) {
vncTimedMsgBox::Do(
"The WinVNC service was successfully registered\n"
"The service may be started from the Control Panel, and will\n"
"automatically be run the next time this machine is reset",
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, "The Service Control Manager could not be contacted - the WinVNC service was not unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK);
}
}
else
{
// Attempt to delete the WinVNC key
if (RegDeleteValue(runservices, szAppName) != ERROR_SUCCESS)
{
RegCloseKey(runservices);
if (!silent) {
MessageBox(NULL, "The WinVNC service could not be unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK);
}
}
RegCloseKey(runservices);
break;
}
// Try to kill any running copy of WinVNC
if (!KillRunningCopy())
{
if (!silent) {
MessageBox(NULL,
"The WinVNC service could not be contacted",
szAppName,
MB_ICONEXCLAMATION | MB_OK);
}
break;
}
// We have successfully removed the service!
if (!silent) {
vncTimedMsgBox::Do("The WinVNC service has been unregistered", 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, "WARNING:The ServiceHelper hook entry could not be removed from the registry", 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, "The WinVNC service could not be stopped", szAppName, MB_ICONEXCLAMATION | MB_OK);
}
}
}
// Now remove the service from the SCM
if (DeleteService(hservice)) {
if (!silent) {
vncTimedMsgBox::Do("The WinVNC service has been unregistered", szAppName, MB_ICONINFORMATION | MB_OK);
}
} else {
DWORD error = GetLastError();
if (error == ERROR_SERVICE_MARKED_FOR_DELETE) {
if (!silent)
MessageBox(NULL, "The WinVNC service is already marked to be unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK);
} else {
if (!silent)
MessageBox(NULL, "The WinVNC service could not be unregistered", szAppName, MB_ICONEXCLAMATION | MB_OK);
}
}
CloseServiceHandle(hservice);
}
else if (!silent)
MessageBox(NULL, "The WinVNC service could not be found", szAppName, MB_ICONEXCLAMATION | MB_OK);
CloseServiceHandle(hsrvmanager);
}
else if (!silent)
MessageBox(NULL, "The Service Control Manager could not be contacted - the WinVNC service was not unregistered", 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?
switch(ctrlcode)
{
case SERVICE_CONTROL_STOP:
// STOP : The service must stop
g_srvstatus.dwCurrentState = SERVICE_STOP_PENDING;
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;
// 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);
sprintf(msgbuff, "%.200s 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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -