转载:http://blog.csdn.net/zdy0_2004/article/details/40461571
#define _WIN32_WINNT 0x502 #define _CRT_SECURE_NO_WARNINGS #include <Windows.h> #include <Shlwapi.h> #include <WtsApi32.h> #include <UserEnv.h> #include <iostream> #include <fstream> #include <atlbase.h> static const char* const lpServiceName = "ProtectService"; static SERVICE_STATUS_HANDLE hServiceStatus = NULL; static SERVICE_STATUS ServiceStatus = {0}; static char szCurDir[MAX_PATH+1] = {0}; static bool bRun = false; static HANDLE hProcess = NULL; static FILE* fLog = NULL; static std::ofstream ofs_log; bool InstallService(); VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv); VOID WINAPI HandlerFunc(DWORD dwControl); HANDLE RunAsLoggedUser(const char* lpPath,char* lpCmdLine); void WorkFunc(); int main(int argc, char **argv) { GetModuleFileName(NULL,szCurDir,MAX_PATH); *strrchr(szCurDir,'\\') = '\0'; char szLogPath[MAX_PATH+1]; sprintf(szLogPath,"%s\\Service.log",szCurDir); fLog = fopen(szLogPath,"a+"); setvbuf(fLog,NULL,_IONBF,1024); ofs_log.open(szLogPath,std::ios::app); SERVICE_TABLE_ENTRY ServiceTable[2]; char szBuffer[30]; strcpy(szBuffer,lpServiceName); ServiceTable[0].lpServiceName = szBuffer; ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; ServiceTable[1].lpServiceName = NULL; ServiceTable[1].lpServiceProc = NULL; // 启动服务的控制分派机线程 if (!StartServiceCtrlDispatcher(ServiceTable)) { ofs_log<<"程序不是以服务方式启动"<<std::endl; std::cout<<"程序不是以服务方式启动,要创建服务并启动吗?y/n:"; if (getchar() == 'y') { // 安装服务 if (!InstallService()) { ofs_log<<"安装服务失败"<<std::endl; std::cout<<"安装服务失败,具体原因请查看日志"<<std::endl; return 1; } ofs_log<<"安装服务成功"<<std::endl; } } return 0; } bool InstallService() { SC_HANDLE hSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (!hSCManager) { ofs_log<<"OpenSCManager失败,错误码为:"<<GetLastError()<<std::endl; return false; } SC_HANDLE hService = OpenService(hSCManager,lpServiceName,SERVICE_QUERY_CONFIG); if (hService) { ofs_log<<"服务已经存在"<<std::endl; CloseServiceHandle(hSCManager); CloseServiceHandle(hService); return false; } char szPath[MAX_PATH+1]; GetModuleFileName(NULL,szPath,MAX_PATH); hService = CreateService(hSCManager, lpServiceName, lpServiceName, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL); if (!hService) { ofs_log<<"CreateService失败,错误码为"<<GetLastError()<<std::endl; CloseServiceHandle(hSCManager); return false; } if (!StartService(hService,0,NULL)) { ofs_log<<"服务安装成功,但是启动服务失败,错误码为:"<<GetLastError()<<std::endl; CloseServiceHandle(hService); CloseServiceHandle(hSCManager); return false; } CloseServiceHandle(hService); CloseServiceHandle(hSCManager); return true; } VOID WINAPI ServiceMain( DWORD dwArgc,LPTSTR *lpszArgv ) { ServiceStatus.dwServiceType = SERVICE_WIN32; ServiceStatus.dwCurrentState = SERVICE_RUNNING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; hServiceStatus = RegisterServiceCtrlHandler(lpServiceName,HandlerFunc); if (!hServiceStatus) { ofs_log<<"RegisterServiceCtrlHandler失败,错误码为:"<<GetLastError()<<std::endl; return; } if (!SetServiceStatus(hServiceStatus,&ServiceStatus)) { ofs_log<<"SetServiceStatus失败,错误码为:"<<GetLastError()<<std::endl; return; } bRun = true; WorkFunc(); } VOID WINAPI HandlerFunc( DWORD dwControl ) { ofs_log<<"收到服务消息:"<<dwControl<<std::endl; if (dwControl == SERVICE_CONTROL_STOP || dwControl == SERVICE_CONTROL_SHUTDOWN) { // 停止服务 ofs_log<<"服务停止"<<std::endl; ServiceStatus.dwCurrentState = SERVICE_STOPPED; bRun = false; if (hProcess) { TerminateProcess(hProcess,0); } } SetServiceStatus(hServiceStatus,&ServiceStatus); } HANDLE RunAsCreator(const char* lpPath, char* lpCmdLine) { if (!PathFileExists(lpPath)) { ofs_log<<"指定的要启动的程序不存在"<<std::endl; return NULL; } char szSubProcCurDir[MAX_PATH]; strcpy(szSubProcCurDir,lpPath); *strrchr(szSubProcCurDir,'\\') = '\0'; STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; si.cb = sizeof(si); if (!CreateProcess(lpPath,lpCmdLine,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,NULL,szSubProcCurDir,&si,&pi)) { ofs_log<<"CreateProcess失败,错误码为:"<<GetLastError()<<std::endl; return NULL; } if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE) { CloseHandle(pi.hThread); } return pi.hProcess; } HANDLE RunAsLoggedUser( const char* lpPath,char* lpCmdLine ) { if (!PathFileExists(lpPath)) { ofs_log<<"指定的要启动的程序不存在"<<std::endl; return NULL; } DWORD dwSid = WTSGetActiveConsoleSessionId(); ofs_log<<"当前登录用户ID为:"<<dwSid<<std::endl; HANDLE hExistingToken = NULL; if (!WTSQueryUserToken(dwSid,&hExistingToken)) { ofs_log<<"WTSQueryUserToken失败,错误码为:"<<GetLastError()<<std::endl; return NULL; } HANDLE hNewToken = NULL; if (!DuplicateTokenEx(hExistingToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hNewToken)) { ofs_log<<"DuplicateTokenEx失败,错误码为:"<<GetLastError()<<std::endl; CloseHandle(hExistingToken); return NULL; } CloseHandle(hExistingToken); LPVOID pEnv = NULL; DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; if (CreateEnvironmentBlock(&pEnv,hNewToken,FALSE)) { dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; } STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; si.cb = sizeof(si); si.lpDesktop = "WinSta0\\Default"; char szSubProcCurDir[MAX_PATH+1]; strcpy(szSubProcCurDir,lpPath); *strrchr(szSubProcCurDir,'\\') = '\0'; if (!CreateProcessAsUser(hNewToken,lpPath,lpCmdLine,NULL,NULL,FALSE,dwCreationFlags,pEnv,szSubProcCurDir,&si,&pi)) { ofs_log<<"CreateProcessAsUser失败,错误码为:"<<GetLastError()<<std::endl; if (pEnv) { DestroyEnvironmentBlock(pEnv); } return NULL; } if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE) { CloseHandle(pi.hThread); } if (pEnv) { DestroyEnvironmentBlock(pEnv); } return pi.hProcess; } HANDLE RunAsSpecifiedUser(const char* lpUserName,const char* lpPassword,const char* lpPath,char* lpCmdLine) { if (!PathFileExists(lpPath)) { ofs_log<<"指定的要启动的程序不存在"<<std::endl; return NULL; } HANDLE hExistingToken = NULL; if (!LogonUser(lpUserName,NULL,lpPassword,LOGON32_LOGON_INTERACTIVE,LOGON32_PROVIDER_DEFAULT,&hExistingToken)) { ofs_log<<"LogonUser失败,错误码为:"<<GetLastError()<<std::endl; return NULL; } HANDLE hNewToken = NULL; if (!DuplicateTokenEx(hExistingToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&hNewToken)) { ofs_log<<"DuplicateTokenEx失败,错误码为:"<<GetLastError()<<std::endl; CloseHandle(hExistingToken); return NULL; } CloseHandle(hExistingToken); LPVOID pEnv = NULL; DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE; if (CreateEnvironmentBlock(&pEnv,hNewToken,FALSE)) { dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT; } STARTUPINFO si = {0}; PROCESS_INFORMATION pi = {0}; si.cb = sizeof(si); //si.lpDesktop = "WinSta0\\Default"; char szSubProcCurDir[MAX_PATH+1]; strcpy(szSubProcCurDir,lpPath); *strrchr(szSubProcCurDir,'\\') = '\0'; if (!CreateProcessAsUser(hNewToken,lpPath,lpCmdLine,NULL,NULL,FALSE,dwCreationFlags,pEnv,szSubProcCurDir,&si,&pi)) { ofs_log<<"CreateProcessAsUser失败,错误码为:"<<GetLastError()<<std::endl; if (pEnv) { DestroyEnvironmentBlock(pEnv); } return NULL; } if (pi.hThread && pi.hThread != INVALID_HANDLE_VALUE) { CloseHandle(pi.hThread); } if (pEnv) { DestroyEnvironmentBlock(pEnv); } return pi.hProcess; } void WorkFunc() { char szIniPath[MAX_PATH+1]; sprintf(szIniPath,"%s\\config.ini",szCurDir); if (!PathFileExists(szCurDir)) { ofs_log<<"配置文件不存在"<<std::endl; } char szProgPath[MAX_PATH+1]; GetPrivateProfileString("PROGRAM","PATH","",szProgPath,MAX_PATH,szIniPath); char szCmdLine[200]; GetPrivateProfileString("PROGRAM","CMD","",szCmdLine,200,szIniPath); int method = GetPrivateProfileInt("USERINFO","METHOD",1,szIniPath); char szUserName[100]; char szPassword[100]; GetPrivateProfileString("USERINFO","UID","",szUserName,99,szIniPath); GetPrivateProfileString("USERINFO","PWD","",szPassword,99,szIniPath); while (bRun) { switch (method) { case 1: hProcess = RunAsCreator(szProgPath,szCmdLine); break; case 2: hProcess = RunAsLoggedUser(szProgPath,szCmdLine); break; case 3: hProcess = RunAsSpecifiedUser(szUserName,szPassword,szProgPath,szCmdLine); break; default: ofs_log<<"未知的启动方式:"<<method<<std::endl; return; } if (!hProcess) { ofs_log<<"创建进程失败失败"<<std::endl; } WaitForSingleObject(hProcess,INFINITE); CloseHandle(hProcess); hProcess = NULL; ofs_log<<"被守护进程退出"<<std::endl; Sleep(2000); } }