📄 ntservice.cpp
字号:
// NTService.cpp
//
// Implementation of CNTService
#include <windows.h>
#include <stdio.h>
#include "NTService.h"
// static variables
CNTService* CNTService::m_pThis = NULL;
CNTService::CNTService(const char* szServiceName)
{
// copy the address of the current object so we can access it from
// the static member callback functions.
// WARNING: This limits the application to only one CNTService object.
m_pThis = this;
// Set the default service name and version
strncpy(m_szServiceName, szServiceName, sizeof(m_szServiceName)-1);
m_iMajorVersion = 1;
m_iMinorVersion = 0;
m_hEventSource = NULL;
// set up the initial service status
m_hServiceStatus = NULL;
m_Status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
m_Status.dwCurrentState = SERVICE_STOPPED;
m_Status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_Status.dwWin32ExitCode = 0;
m_Status.dwServiceSpecificExitCode = 0;
m_Status.dwCheckPoint = 0;
m_Status.dwWaitHint = 0;
m_bIsRunning = FALSE;
}
CNTService::~CNTService()
{
DebugMsg("CNTService::~CNTService()");
if (m_hEventSource) {
::DeregisterEventSource(m_hEventSource);
}
}
////////////////////////////////////////////////////////////////////////////////////////
// Default command line argument parsing
// Returns TRUE if it found an arg it recognised, FALSE if not
// Note: processing some arguments causes output to stdout to be generated.
BOOL CNTService::ParseStandardArgs(int argc, char* argv[])
{
// See if we have any command line args we recognise
if (argc <= 1) return FALSE;
if (_stricmp(argv[1], "-v") == 0) {
// Spit out version info
printf("%s Version %d.%d\n",
m_szServiceName, m_iMajorVersion, m_iMinorVersion);
printf("The service is %s installed\n",
IsInstalled() ? "currently" : "not");
return TRUE; // say we processed the argument
} else if (_stricmp(argv[1], "-i") == 0) {
// Request to install.
if (IsInstalled()) {
printf("%s is already installed\n", m_szServiceName);
} else {
// Try and install the copy that's running
if (Install()) {
printf("%s installed\n", m_szServiceName);
} else {
printf("%s failed to install. Error %d\n", m_szServiceName, GetLastError());
}
}
return TRUE; // say we processed the argument
} else if (_stricmp(argv[1], "-u") == 0) {
// Request to uninstall.
if (!IsInstalled()) {
printf("%s is not installed\n", m_szServiceName);
} else {
// Try and remove the copy that's installed
if (Uninstall()) {
// Get the executable file path
char szFilePath[_MAX_PATH];
::GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
printf("%s removed. (You must delete the file (%s) yourself.)\n",
m_szServiceName, szFilePath);
} else {
printf("Could not remove %s. Error %d\n", m_szServiceName, GetLastError());
}
}
return TRUE; // say we processed the argument
}
else if (_stricmp(argv[1], "-d") == 0)
{
if(IsInstalled()&&m_hServiceStatus==SERVICE_RUNNING)
{
AddLog("服务程序正在运行,请先关闭%s再进行调试。",szSubServiceName);
return TRUE;
}
m_bIsRunning=1;
Run();
return TRUE; // say we processed the argument
}
// Don't recognise the args
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////
// Install/uninstall routines
// Test if the service is currently installed
BOOL CNTService::IsInstalled()
{
BOOL bResult = FALSE;
// Open the Service Control Manager
SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access
if (hSCM) {
// Try to open the service
SC_HANDLE hService = ::OpenService(hSCM,
m_szServiceName,
SERVICE_QUERY_CONFIG);
if (hService) {
bResult = TRUE;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bResult;
}
BOOL CNTService::Install()
{
// Open the Service Control Manager
SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access
if (!hSCM) return FALSE;
// Get the executable file path
char szFilePath[_MAX_PATH];
::GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
// Create the service
SC_HANDLE hService = ::CreateService(hSCM,
m_szServiceName,
m_szServiceName,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_DEMAND_START, // start condition
SERVICE_ERROR_NORMAL,
szFilePath,
NULL,
NULL,
NULL,
NULL,
NULL);
if (!hService) {
::CloseServiceHandle(hSCM);
return FALSE;
}
// make registry entries to support logging messages
// Add the source name as a subkey under the Application
// key in the EventLog service portion of the registry.
char szKey[256];
HKEY hKey = NULL;
strcpy(szKey, "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\");
strcat(szKey, m_szServiceName);
if (::RegCreateKey(HKEY_LOCAL_MACHINE, szKey, &hKey) != ERROR_SUCCESS) {
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return FALSE;
}
// Add the Event ID message-file name to the 'EventMessageFile' subkey.
::RegSetValueEx(hKey,
"EventMessageFile",
0,
REG_EXPAND_SZ,
(CONST BYTE*)szFilePath,
strlen(szFilePath) + 1);
// Set the supported types flags.
DWORD dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
::RegSetValueEx(hKey,
"TypesSupported",
0,
REG_DWORD,
(CONST BYTE*)&dwData,
sizeof(DWORD));
::RegCloseKey(hKey);
LogEvent(EVENTLOG_INFORMATION_TYPE, EVMSG_INSTALLED, m_szServiceName);
// tidy up
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
}
BOOL CNTService::Uninstall()
{
// Open the Service Control Manager
SC_HANDLE hSCM = ::OpenSCManager(NULL, // local machine
NULL, // ServicesActive database
SC_MANAGER_ALL_ACCESS); // full access
if (!hSCM) return FALSE;
BOOL bResult = FALSE;
SC_HANDLE hService = ::OpenService(hSCM,
m_szServiceName,
DELETE);
if (hService) {
if (::DeleteService(hService)) {
LogEvent(EVENTLOG_INFORMATION_TYPE, EVMSG_REMOVED, m_szServiceName);
bResult = TRUE;
} else {
LogEvent(EVENTLOG_ERROR_TYPE, EVMSG_NOTREMOVED, m_szServiceName);
}
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
return bResult;
}
///////////////////////////////////////////////////////////////////////////////////////
// Logging functions
// This function makes an entry into the application event log
void CNTService::LogEvent(WORD wType, DWORD dwID,
const char* pszS1,
const char* pszS2,
const char* pszS3)
{
const char* ps[3];
ps[0] = pszS1;
ps[1] = pszS2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -