|
@@ -0,0 +1,1718 @@
|
|
|
+#include "stdafx.h"
|
|
|
+#include "WindowService.h"
|
|
|
+#include <psapi.h>
|
|
|
+#include <tlhelp32.h>
|
|
|
+#pragma comment ( lib, "psapi.lib" )
|
|
|
+#include <Aclapi.h>
|
|
|
+#include <strsafe.h>
|
|
|
+#include <shlwapi.h>
|
|
|
+
|
|
|
+namespace WindowsService
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ SERVICE_STATUS_HANDLE g_SvcStatusHandle;
|
|
|
+ SERVICE_STATUS g_SvcStatus;
|
|
|
+ HANDLE g_hCtrlSvc = NULL;
|
|
|
+ TCHAR g_szlpSvrDescription[MAX_PATH] = _T("");
|
|
|
+ TCHAR g_szSvcName[MAX_PATH] = _T("");
|
|
|
+ WorkStartCallback g_lpStartWorkCallBack = NULL;
|
|
|
+ WorkEndofCallback g_lpEndofWorkCallBack = NULL;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ int InitWinSock()
|
|
|
+ {
|
|
|
+ WORD wVersionRequested;
|
|
|
+ WSADATA wsaData;
|
|
|
+ int nErrCode;
|
|
|
+
|
|
|
+ wVersionRequested = MAKEWORD(2, 2);
|
|
|
+ nErrCode = WSAStartup( wVersionRequested, &wsaData );
|
|
|
+ if ( 0 != nErrCode )
|
|
|
+ return -1;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void InitSvcVar()
|
|
|
+ {
|
|
|
+ g_SvcStatusHandle = NULL;
|
|
|
+ g_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
|
|
+ g_SvcStatus.dwCurrentState = SERVICE_STOPPED;
|
|
|
+ g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
|
|
|
+ g_SvcStatus.dwWin32ExitCode = 0;
|
|
|
+ g_SvcStatus.dwServiceSpecificExitCode = 0;
|
|
|
+ g_SvcStatus.dwCheckPoint = 0;
|
|
|
+ g_SvcStatus.dwWaitHint = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BOOL IsSvcInstalled()
|
|
|
+ {
|
|
|
+ BOOL bResult = FALSE;
|
|
|
+
|
|
|
+ SC_HANDLE schSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (schSCM != NULL)
|
|
|
+ {
|
|
|
+ SC_HANDLE schSvc = ::OpenService(schSCM, g_szSvcName, SERVICE_QUERY_CONFIG);
|
|
|
+ if (schSvc != NULL)
|
|
|
+ {
|
|
|
+ bResult = TRUE;
|
|
|
+ ::CloseServiceHandle(schSvc);
|
|
|
+ }
|
|
|
+ ::CloseServiceHandle(schSCM);
|
|
|
+ }
|
|
|
+
|
|
|
+ return bResult;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BOOL SvcInstall()
|
|
|
+ {
|
|
|
+
|
|
|
+ TCHAR szFilePath[MAX_PATH];
|
|
|
+ if ( 0 == ::GetModuleFileName(NULL, szFilePath, MAX_PATH) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Cannot Install Service (%d)\n"), GetLastError());
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ SC_HANDLE schSCM = ::OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS
|
|
|
+ );
|
|
|
+
|
|
|
+ if (schSCM == NULL)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ SC_HANDLE schSvc = ::CreateService(
|
|
|
+ schSCM,
|
|
|
+ g_szSvcName,
|
|
|
+ g_szSvcName,
|
|
|
+ SERVICE_ALL_ACCESS,
|
|
|
+ SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
|
|
|
+ SERVICE_AUTO_START,
|
|
|
+ SERVICE_ERROR_NORMAL,
|
|
|
+ szFilePath,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ _T(""),
|
|
|
+ NULL,
|
|
|
+ NULL
|
|
|
+ );
|
|
|
+
|
|
|
+ if ( schSvc == NULL )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("CreateService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSvc);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ SERVICE_DESCRIPTION ServiceDesc;
|
|
|
+ ServiceDesc.lpDescription = g_szlpSvrDescription;
|
|
|
+ ::ChangeServiceConfig2(schSvc, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc);
|
|
|
+
|
|
|
+
|
|
|
+ ::CloseServiceHandle(schSvc);
|
|
|
+ ::CloseServiceHandle(schSCM);
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void WINAPI ServiceMain()
|
|
|
+ {
|
|
|
+
|
|
|
+ g_SvcStatusHandle = RegisterServiceCtrlHandler(g_szSvcName, SvcCtrlHandler);
|
|
|
+ if (g_SvcStatusHandle == NULL)
|
|
|
+ {
|
|
|
+ SvcReportEvent(_T("Handler not installed"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ g_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
|
|
+ g_SvcStatus.dwServiceSpecificExitCode = 0;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 0, 1, 3000);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ g_hCtrlSvc = ::CreateEvent( NULL,TRUE, FALSE, _T("CtrlService::g_hCtrlSvc"));
|
|
|
+ if (g_hCtrlSvc == NULL)
|
|
|
+ {
|
|
|
+
|
|
|
+ ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0, 1, 0);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0, 0, 0);
|
|
|
+
|
|
|
+
|
|
|
+ if ( g_lpStartWorkCallBack )
|
|
|
+ g_lpStartWorkCallBack();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ WaitForSingleObject(g_hCtrlSvc,INFINITE);
|
|
|
+ CloseHandle(g_hCtrlSvc);
|
|
|
+
|
|
|
+
|
|
|
+ if ( g_lpEndofWorkCallBack )
|
|
|
+ g_lpEndofWorkCallBack();
|
|
|
+
|
|
|
+ SvcReportEvent(_T("Service stopped"));
|
|
|
+
|
|
|
+
|
|
|
+ ReportSvcStatus(SERVICE_STOPPED,NO_ERROR,0,0,0);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void WINAPI SvcCtrlHandler(IN DWORD dwControlCode)
|
|
|
+ {
|
|
|
+ BOOL bsucc = FALSE;
|
|
|
+ switch (dwControlCode)
|
|
|
+ {
|
|
|
+ case SERVICE_CONTROL_SHUTDOWN:
|
|
|
+ case SERVICE_CONTROL_STOP:
|
|
|
+ bsucc = ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, 1, 0);
|
|
|
+ if (bsucc)
|
|
|
+ KillService();
|
|
|
+ break;
|
|
|
+ case SERVICE_CONTROL_PAUSE:
|
|
|
+
|
|
|
+ break;
|
|
|
+ case SERVICE_CONTROL_CONTINUE:
|
|
|
+
|
|
|
+ break;
|
|
|
+ case SERVICE_CONTROL_INTERROGATE:
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ SvcReportEvent(_T("Bad service request"));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BOOL ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint, DWORD dwWaitHint)
|
|
|
+ {
|
|
|
+ BOOL bSuccess;
|
|
|
+
|
|
|
+ g_SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
|
|
+ g_SvcStatus.dwCurrentState = dwCurrentState;
|
|
|
+ g_SvcStatus.dwWaitHint = dwWaitHint;
|
|
|
+
|
|
|
+ if( dwCurrentState == SERVICE_START_PENDING )
|
|
|
+ {
|
|
|
+ g_SvcStatus.dwControlsAccepted = 0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ g_SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN ;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( (dwCurrentState == SERVICE_RUNNING ) || ( dwCurrentState == SERVICE_STOPPED ) )
|
|
|
+ g_SvcStatus.dwCheckPoint = 0;
|
|
|
+ else
|
|
|
+ g_SvcStatus.dwCheckPoint = dwCheckPoint++;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if(dwServiceSpecificExitCode == 0)
|
|
|
+ {
|
|
|
+ g_SvcStatus.dwWin32ExitCode = dwWin32ExitCode;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ g_SvcStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
|
|
|
+ }
|
|
|
+ g_SvcStatus.dwServiceSpecificExitCode = dwServiceSpecificExitCode;
|
|
|
+
|
|
|
+
|
|
|
+ bSuccess = SetServiceStatus( g_SvcStatusHandle,&g_SvcStatus);
|
|
|
+ if( !bSuccess )
|
|
|
+ {
|
|
|
+ SvcReportEvent(_T("Set Service Status failed (%d) "), GetLastError());
|
|
|
+ KillService();
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ void KillService()
|
|
|
+ {
|
|
|
+
|
|
|
+ SetEvent(g_hCtrlSvc);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void SvcReportEvent(IN LPCTSTR pFormat, ...)
|
|
|
+ {
|
|
|
+ TCHAR szReport[MAX_PATH] = {0};
|
|
|
+ HANDLE hEventSource;
|
|
|
+ LPCTSTR lpszStrings[2];
|
|
|
+ va_list pArg = NULL;
|
|
|
+
|
|
|
+ va_start(pArg, pFormat);
|
|
|
+ StringCchVPrintf(szReport, MAX_PATH, pFormat, pArg);
|
|
|
+ va_end(pArg);
|
|
|
+
|
|
|
+ hEventSource = RegisterEventSource(NULL, g_szSvcName);
|
|
|
+ if (hEventSource != NULL)
|
|
|
+ {
|
|
|
+ lpszStrings[0] = g_szSvcName;
|
|
|
+ lpszStrings[1] = szReport;
|
|
|
+
|
|
|
+ ReportEvent(
|
|
|
+ hEventSource,
|
|
|
+ EVENTLOG_INFORMATION_TYPE,
|
|
|
+ 0,
|
|
|
+ 0,
|
|
|
+ NULL,
|
|
|
+ 2,
|
|
|
+ 0,
|
|
|
+ lpszStrings,
|
|
|
+ NULL
|
|
|
+ );
|
|
|
+
|
|
|
+ DeregisterEventSource(hEventSource);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void StartSvc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("要启动的服务名空\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ SC_HANDLE schSCM;
|
|
|
+ SC_HANDLE schService;
|
|
|
+ SERVICE_STATUS_PROCESS ssStatus;
|
|
|
+ DWORD dwOldCheckPoint;
|
|
|
+ DWORD dwStartTickCount;
|
|
|
+ DWORD dwWaitTime;
|
|
|
+ DWORD dwBytesNeeded;
|
|
|
+
|
|
|
+
|
|
|
+ schSCM = OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (NULL == schSCM)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ schService = OpenService(
|
|
|
+ schSCM,
|
|
|
+ lpSvcName,
|
|
|
+ SERVICE_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (schService == NULL)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (!QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE) &ssStatus,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if(ssStatus.dwCurrentState != SERVICE_STOPPED && ssStatus.dwCurrentState != SERVICE_STOP_PENDING)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Cannot start the service because it is already running\n"));
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ dwStartTickCount = GetTickCount();
|
|
|
+ dwOldCheckPoint = ssStatus.dwCheckPoint;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ while (ssStatus.dwCurrentState == SERVICE_STOP_PENDING)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ dwWaitTime = ssStatus.dwWaitHint / 10;
|
|
|
+
|
|
|
+ if( dwWaitTime < 1000 )
|
|
|
+ dwWaitTime = 1000;
|
|
|
+ else if ( dwWaitTime > 10000 )
|
|
|
+ dwWaitTime = 10000;
|
|
|
+
|
|
|
+ Sleep( dwWaitTime );
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE) &ssStatus,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ dwStartTickCount = GetTickCount();
|
|
|
+ dwOldCheckPoint = ssStatus.dwCheckPoint;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Timeout waiting for service to stop\n"));
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!StartService(
|
|
|
+ schService,
|
|
|
+ 0,
|
|
|
+ NULL) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("StartService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ else printf("Service start pending...\n");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE) &ssStatus,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ dwStartTickCount = GetTickCount();
|
|
|
+ dwOldCheckPoint = ssStatus.dwCheckPoint;
|
|
|
+
|
|
|
+ while (ssStatus.dwCurrentState == SERVICE_START_PENDING)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ dwWaitTime = ssStatus.dwWaitHint / 10;
|
|
|
+
|
|
|
+ if( dwWaitTime < 1000 )
|
|
|
+ dwWaitTime = 1000;
|
|
|
+ else if ( dwWaitTime > 10000 )
|
|
|
+ dwWaitTime = 10000;
|
|
|
+
|
|
|
+ Sleep( dwWaitTime );
|
|
|
+
|
|
|
+
|
|
|
+ if (!QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE) &ssStatus,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceStatusEx failed (%d)\n"), GetLastError());
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ssStatus.dwCheckPoint > dwOldCheckPoint )
|
|
|
+ {
|
|
|
+
|
|
|
+ dwStartTickCount = GetTickCount();
|
|
|
+ dwOldCheckPoint = ssStatus.dwCheckPoint;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
|
|
|
+ {
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (ssStatus.dwCurrentState == SERVICE_RUNNING)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Service started successfully.\n"));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Service not started. \n"));
|
|
|
+ _tprintf_s(_T(" Current State: %d\n"), ssStatus.dwCurrentState);
|
|
|
+ _tprintf_s(_T(" Exit Code: %d\n"), ssStatus.dwWin32ExitCode);
|
|
|
+ _tprintf_s(_T(" Check Point: %d\n"), ssStatus.dwCheckPoint);
|
|
|
+ _tprintf_s(_T(" Wait Hint: %d\n"), ssStatus.dwWaitHint);
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void UpdateSvcDacl(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ return;
|
|
|
+
|
|
|
+ EXPLICIT_ACCESS ea;
|
|
|
+ SECURITY_DESCRIPTOR sd;
|
|
|
+ PSECURITY_DESCRIPTOR psd = NULL;
|
|
|
+ PACL pacl = NULL;
|
|
|
+ PACL pNewAcl = NULL;
|
|
|
+ BOOL bDaclPresent = FALSE;
|
|
|
+ BOOL bDaclDefaulted = FALSE;
|
|
|
+ DWORD dwError = 0;
|
|
|
+ DWORD dwSize = 0;
|
|
|
+ DWORD dwBytesNeeded = 0;
|
|
|
+
|
|
|
+ SC_HANDLE schSCManager;
|
|
|
+ SC_HANDLE schService;
|
|
|
+
|
|
|
+
|
|
|
+ schSCManager = OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (NULL == schSCManager)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ schService = OpenService(
|
|
|
+ schSCManager,
|
|
|
+ lpSvcName,
|
|
|
+ READ_CONTROL | WRITE_DAC);
|
|
|
+
|
|
|
+ if (schService == NULL)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSCManager);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!QueryServiceObjectSecurity(schService,
|
|
|
+ DACL_SECURITY_INFORMATION,
|
|
|
+ &psd,
|
|
|
+ 0,
|
|
|
+ &dwBytesNeeded))
|
|
|
+ {
|
|
|
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
|
|
|
+ {
|
|
|
+ dwSize = dwBytesNeeded;
|
|
|
+ psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
|
|
|
+ if (psd == NULL)
|
|
|
+ {
|
|
|
+
|
|
|
+ _tprintf_s(_T("HeapAlloc failed\n"));
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!QueryServiceObjectSecurity(schService,
|
|
|
+ DACL_SECURITY_INFORMATION, psd, dwSize, &dwBytesNeeded))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError());
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceObjectSecurity failed (%d)\n"), GetLastError());
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
|
|
|
+ &bDaclDefaulted))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("GetSecurityDescriptorDacl failed(%d)\n"), GetLastError());
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BuildExplicitAccessWithName(&ea, TEXT("GUEST"),
|
|
|
+ SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
|
|
|
+ SET_ACCESS, NO_INHERITANCE);
|
|
|
+
|
|
|
+ dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
|
|
|
+ if (dwError != ERROR_SUCCESS)
|
|
|
+ {
|
|
|
+ printf("SetEntriesInAcl failed(%d)\n", dwError);
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!InitializeSecurityDescriptor(&sd,
|
|
|
+ SECURITY_DESCRIPTOR_REVISION))
|
|
|
+ {
|
|
|
+ printf("InitializeSecurityDescriptor failed(%d)\n", GetLastError());
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
|
|
|
+ {
|
|
|
+ printf("SetSecurityDescriptorDacl failed(%d)\n", GetLastError());
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (!SetServiceObjectSecurity(schService,
|
|
|
+ DACL_SECURITY_INFORMATION, &sd))
|
|
|
+ {
|
|
|
+ printf("SetServiceObjectSecurity failed(%d)\n", GetLastError());
|
|
|
+ goto dacl_cleanup;
|
|
|
+ }
|
|
|
+ else printf("Service DACL updated successfully\n");
|
|
|
+
|
|
|
+dacl_cleanup:
|
|
|
+ CloseServiceHandle(schSCManager);
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+
|
|
|
+ if(NULL != pNewAcl)
|
|
|
+ LocalFree((HLOCAL)pNewAcl);
|
|
|
+ if(NULL != psd)
|
|
|
+ HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ void DoStopSvc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("指定要停止的服务名无效\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SERVICE_STATUS_PROCESS ssp;
|
|
|
+ DWORD dwStartTime = GetTickCount();
|
|
|
+ DWORD dwBytesNeeded;
|
|
|
+ DWORD dwTimeout = 30000;
|
|
|
+ DWORD dwWaitTime;
|
|
|
+
|
|
|
+ SC_HANDLE schSCManager;
|
|
|
+ SC_HANDLE schService;
|
|
|
+
|
|
|
+
|
|
|
+ schSCManager = OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (NULL == schSCManager)
|
|
|
+ {
|
|
|
+ printf("OpenSCManager failed (%d)\n", GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ schService = OpenService(
|
|
|
+ schSCManager,
|
|
|
+ lpSvcName,
|
|
|
+ SERVICE_STOP |
|
|
|
+ SERVICE_QUERY_STATUS |
|
|
|
+ SERVICE_ENUMERATE_DEPENDENTS);
|
|
|
+
|
|
|
+ if (schService == NULL)
|
|
|
+ {
|
|
|
+ printf("OpenService failed (%d)\n", GetLastError());
|
|
|
+ CloseServiceHandle(schSCManager);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if ( !QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE)&ssp,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ssp.dwCurrentState == SERVICE_STOPPED )
|
|
|
+ {
|
|
|
+ printf("Service is already stopped.\n");
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ while ( ssp.dwCurrentState == SERVICE_STOP_PENDING )
|
|
|
+ {
|
|
|
+ printf("Service stop pending...\n");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ dwWaitTime = ssp.dwWaitHint / 10;
|
|
|
+
|
|
|
+ if( dwWaitTime < 1000 )
|
|
|
+ dwWaitTime = 1000;
|
|
|
+ else if ( dwWaitTime > 10000 )
|
|
|
+ dwWaitTime = 10000;
|
|
|
+
|
|
|
+ Sleep( dwWaitTime );
|
|
|
+
|
|
|
+ if ( !QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE)&ssp,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ printf("QueryServiceStatusEx failed (%d)\n", GetLastError());
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ssp.dwCurrentState == SERVICE_STOPPED )
|
|
|
+ {
|
|
|
+ printf("Service stopped successfully.\n");
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( GetTickCount() - dwStartTime > dwTimeout )
|
|
|
+ {
|
|
|
+ printf("Service stop timed out.\n");
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ StopDependentServices();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if ( !ControlService(
|
|
|
+ schService,
|
|
|
+ SERVICE_CONTROL_STOP,
|
|
|
+ (LPSERVICE_STATUS) &ssp ) )
|
|
|
+ {
|
|
|
+ printf( "ControlService failed (%d)\n", GetLastError() );
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ while ( ssp.dwCurrentState != SERVICE_STOPPED )
|
|
|
+ {
|
|
|
+ Sleep( ssp.dwWaitHint );
|
|
|
+ if ( !QueryServiceStatusEx(
|
|
|
+ schService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE)&ssp,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ {
|
|
|
+ printf( "QueryServiceStatusEx failed (%d)\n", GetLastError() );
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( ssp.dwCurrentState == SERVICE_STOPPED )
|
|
|
+ break;
|
|
|
+
|
|
|
+ if ( GetTickCount() - dwStartTime > dwTimeout )
|
|
|
+ {
|
|
|
+ printf( "Wait timed out\n" );
|
|
|
+ goto stop_cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ printf("Service stopped successfully\n");
|
|
|
+
|
|
|
+stop_cleanup:
|
|
|
+ CloseServiceHandle(schService);
|
|
|
+ CloseServiceHandle(schSCManager);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL StopDependentServices()
|
|
|
+ {
|
|
|
+ DWORD i;
|
|
|
+ DWORD dwBytesNeeded;
|
|
|
+ DWORD dwCount;
|
|
|
+
|
|
|
+ LPENUM_SERVICE_STATUS lpDependencies = NULL;
|
|
|
+ ENUM_SERVICE_STATUS ess;
|
|
|
+ SC_HANDLE hDepService;
|
|
|
+ SERVICE_STATUS_PROCESS ssp;
|
|
|
+
|
|
|
+ DWORD dwStartTime = GetTickCount();
|
|
|
+ DWORD dwTimeout = 30000;
|
|
|
+
|
|
|
+ SC_HANDLE schSCManager = NULL;
|
|
|
+ SC_HANDLE schService = NULL;
|
|
|
+
|
|
|
+
|
|
|
+ if ( EnumDependentServices( schService, SERVICE_ACTIVE,
|
|
|
+ lpDependencies, 0, &dwBytesNeeded, &dwCount ) )
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if ( GetLastError() != ERROR_MORE_DATA )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+
|
|
|
+ lpDependencies = (LPENUM_SERVICE_STATUS) HeapAlloc(
|
|
|
+ GetProcessHeap(), HEAP_ZERO_MEMORY, dwBytesNeeded );
|
|
|
+
|
|
|
+ if ( !lpDependencies )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ __try {
|
|
|
+
|
|
|
+ if ( !EnumDependentServices( schService, SERVICE_ACTIVE,
|
|
|
+ lpDependencies, dwBytesNeeded, &dwBytesNeeded,
|
|
|
+ &dwCount ) )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ for ( i = 0; i < dwCount; i++ )
|
|
|
+ {
|
|
|
+ ess = *(lpDependencies + i);
|
|
|
+
|
|
|
+ hDepService = OpenService( schSCManager,
|
|
|
+ ess.lpServiceName,
|
|
|
+ SERVICE_STOP | SERVICE_QUERY_STATUS );
|
|
|
+
|
|
|
+ if ( !hDepService )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ __try {
|
|
|
+
|
|
|
+ if ( !ControlService( hDepService,
|
|
|
+ SERVICE_CONTROL_STOP,
|
|
|
+ (LPSERVICE_STATUS) &ssp ) )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+
|
|
|
+ while ( ssp.dwCurrentState != SERVICE_STOPPED )
|
|
|
+ {
|
|
|
+ Sleep( ssp.dwWaitHint );
|
|
|
+ if ( !QueryServiceStatusEx(
|
|
|
+ hDepService,
|
|
|
+ SC_STATUS_PROCESS_INFO,
|
|
|
+ (LPBYTE)&ssp,
|
|
|
+ sizeof(SERVICE_STATUS_PROCESS),
|
|
|
+ &dwBytesNeeded ) )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ if ( ssp.dwCurrentState == SERVICE_STOPPED )
|
|
|
+ break;
|
|
|
+
|
|
|
+ if ( GetTickCount() - dwStartTime > dwTimeout )
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ __finally
|
|
|
+ {
|
|
|
+
|
|
|
+ CloseServiceHandle( hDepService );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ __finally
|
|
|
+ {
|
|
|
+
|
|
|
+ HeapFree( GetProcessHeap(), 0, lpDependencies );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return TRUE;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void DoQuerySvc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("要查询的服务名称无效\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SC_HANDLE hSCM;
|
|
|
+ SC_HANDLE hSvc;
|
|
|
+ LPQUERY_SERVICE_CONFIG lpsc;
|
|
|
+ LPSERVICE_DESCRIPTION lpsd;
|
|
|
+ DWORD dwBytesNeeded, cbBfuSize, dwError;
|
|
|
+
|
|
|
+
|
|
|
+ hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
+ if ( hSCM == NULL )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ hSvc = OpenService(
|
|
|
+ hSCM,
|
|
|
+ lpSvcName,
|
|
|
+ SERVICE_QUERY_CONFIG
|
|
|
+ );
|
|
|
+ if ( hSvc == NULL )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(hSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if ( !QueryServiceConfig( hSvc, NULL, 0, &dwBytesNeeded) )
|
|
|
+ {
|
|
|
+ dwError = GetLastError();
|
|
|
+ if ( ERROR_INSUFFICIENT_BUFFER == dwError )
|
|
|
+ {
|
|
|
+ cbBfuSize = dwBytesNeeded;
|
|
|
+ lpsc = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbBfuSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QueryServiceConfig failed (%d)\n"), dwError);
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( !QueryServiceConfig(hSvc, lpsc, cbBfuSize, &dwBytesNeeded) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QuerySericeConfig failed (%d)\n"), GetLastError());
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( !QueryServiceConfig2( hSvc, SERVICE_CONFIG_DESCRIPTION, NULL, 0, &dwBytesNeeded) )
|
|
|
+ {
|
|
|
+ dwError = GetLastError();
|
|
|
+ if ( ERROR_INSUFFICIENT_BUFFER == dwError )
|
|
|
+ {
|
|
|
+ cbBfuSize = dwBytesNeeded;
|
|
|
+ lpsd = (LPSERVICE_DESCRIPTION)LocalAlloc(LMEM_FIXED, cbBfuSize);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError());
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( !QueryServiceConfig2( hSvc, SERVICE_CONFIG_DESCRIPTION, (LPBYTE)lpsd, cbBfuSize, &dwBytesNeeded) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("QuerySericeConfig2 failed (%d)\n"), GetLastError());
|
|
|
+ goto cleanup;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ _tprintf(TEXT("%s configuration: \n"), g_szSvcName);
|
|
|
+ _tprintf(TEXT(" Type: 0x%x\n"), lpsc->dwServiceType);
|
|
|
+ _tprintf(TEXT(" Start Type: 0x%x\n"), lpsc->dwStartType);
|
|
|
+ _tprintf(TEXT(" Error Control: 0x%x\n"), lpsc->dwErrorControl);
|
|
|
+ _tprintf(TEXT(" Binary path: %s\n"), lpsc->lpBinaryPathName);
|
|
|
+ _tprintf(TEXT(" Account: %s\n"), lpsc->lpServiceStartName);
|
|
|
+
|
|
|
+ if (lpsd->lpDescription != NULL && lstrcmp(lpsd->lpDescription, TEXT("")) != 0)
|
|
|
+ _tprintf(TEXT(" Description: %s\n"), lpsd->lpDescription);
|
|
|
+ if (lpsc->lpLoadOrderGroup != NULL && lstrcmp(lpsc->lpLoadOrderGroup, TEXT("")) != 0)
|
|
|
+ _tprintf(TEXT(" Load order group: %s\n"), lpsc->lpLoadOrderGroup);
|
|
|
+ if (lpsc->dwTagId != 0)
|
|
|
+ _tprintf(TEXT(" Tag ID: %d\n"), lpsc->dwTagId);
|
|
|
+ if (lpsc->lpDependencies != NULL && lstrcmp(lpsc->lpDependencies, TEXT("")) != 0)
|
|
|
+ _tprintf(TEXT(" Dependencies: %s\n"), lpsc->lpDependencies);
|
|
|
+
|
|
|
+
|
|
|
+ LocalFree(lpsc);
|
|
|
+ LocalFree(lpsd);
|
|
|
+
|
|
|
+cleanup:
|
|
|
+ CloseServiceHandle(hSvc);
|
|
|
+ CloseServiceHandle(hSCM);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void DoDisableSvc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("要禁用的服务名称无效\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SC_HANDLE schSCM;
|
|
|
+ SC_HANDLE schSvc;
|
|
|
+
|
|
|
+
|
|
|
+ schSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
|
|
|
+ if ( schSCM == NULL )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ schSvc = OpenService(schSCM, lpSvcName, SERVICE_CHANGE_CONFIG );
|
|
|
+ if ( schSvc == NULL )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ( !ChangeServiceConfig(
|
|
|
+ schSvc,
|
|
|
+ SERVICE_NO_CHANGE,
|
|
|
+ SERVICE_DISABLED,
|
|
|
+ SERVICE_NO_CHANGE,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError());
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseServiceHandle(schSvc);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void DoEnableSvc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("要启用的服务名称无效\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SC_HANDLE schSCM;
|
|
|
+ SC_HANDLE schSvc;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ schSCM = OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (NULL == schSCM)
|
|
|
+ {
|
|
|
+ printf("OpenSCManager failed (%d)\n", GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ schSvc = OpenService(
|
|
|
+ schSCM,
|
|
|
+ lpSvcName,
|
|
|
+ SERVICE_CHANGE_CONFIG);
|
|
|
+
|
|
|
+ if (schSvc == NULL)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (! ChangeServiceConfig(
|
|
|
+ schSvc,
|
|
|
+ SERVICE_NO_CHANGE,
|
|
|
+ SERVICE_DEMAND_START,
|
|
|
+ SERVICE_NO_CHANGE,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ NULL) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("ChangeServiceConfig failed (%d)\n"), GetLastError());
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Service enabled successfully.\n"));
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseServiceHandle(schSvc);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void DoUpdateSvcDesc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("要更新描述的服务名称无效\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SC_HANDLE schSCM;
|
|
|
+ SC_HANDLE schSvc;
|
|
|
+ SERVICE_DESCRIPTION sd;
|
|
|
+ LPTSTR szDesc = TEXT("This is a test description");
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ schSCM = OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (NULL == schSCM)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ schSvc = OpenService(
|
|
|
+ schSCM,
|
|
|
+ lpSvcName,
|
|
|
+ SERVICE_CHANGE_CONFIG);
|
|
|
+
|
|
|
+ if (schSvc == NULL)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ sd.lpDescription = szDesc;
|
|
|
+
|
|
|
+ if( !ChangeServiceConfig2(
|
|
|
+ schSvc,
|
|
|
+ SERVICE_CONFIG_DESCRIPTION,
|
|
|
+ &sd) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("ChangeServiceConfig2 failed\n"));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Service description updated successfully.\n"));
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseServiceHandle(schSvc);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void DoDeleteSvc(IN LPCTSTR lpSvcName)
|
|
|
+ {
|
|
|
+ if ( lpSvcName == NULL || lpSvcName[0] == _T('\0'))
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("要删除的服务名称无效\n"));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ SC_HANDLE schSCM;
|
|
|
+ SC_HANDLE schSvc;
|
|
|
+ SERVICE_STATUS ssStatus;
|
|
|
+
|
|
|
+
|
|
|
+ schSCM = OpenSCManager(
|
|
|
+ NULL,
|
|
|
+ NULL,
|
|
|
+ SC_MANAGER_ALL_ACCESS);
|
|
|
+
|
|
|
+ if (NULL == schSCM)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenSCManager failed (%d)\n"), GetLastError());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ schSvc = OpenService(
|
|
|
+ schSCM,
|
|
|
+ lpSvcName,
|
|
|
+ SERVICE_STOP|DELETE
|
|
|
+ );
|
|
|
+
|
|
|
+ if (schSvc == NULL)
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("OpenService failed (%d)\n"), GetLastError());
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if ( !::ControlService(schSvc, SERVICE_CONTROL_STOP, &ssStatus) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("删除服务前停止服务失败 (%d)\n"), GetLastError());
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if ( !DeleteService(schSvc) )
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("DeleteService failed (%d)\n"), GetLastError());
|
|
|
+ SvcReportEvent(_T("Service could not be deleted"));
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _tprintf_s(_T("Service deleted successfully\n"));
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseServiceHandle(schSvc);
|
|
|
+ CloseServiceHandle(schSCM);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ void SetCallBack( IN LPVOID lpStartWorkCallBack, IN LPVOID lpEndofWorkCallBack )
|
|
|
+ {
|
|
|
+ if ( g_lpStartWorkCallBack == NULL )
|
|
|
+ g_lpStartWorkCallBack = (WorkEndofCallback)lpStartWorkCallBack;
|
|
|
+
|
|
|
+ if ( g_lpEndofWorkCallBack == NULL )
|
|
|
+ g_lpEndofWorkCallBack = (WorkEndofCallback)lpEndofWorkCallBack;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BOOL StartProcess( IN LPCTSTR lpExePath )
|
|
|
+ {
|
|
|
+#if 0
|
|
|
+ if( !lpExePath || !PathFileExists(lpExePath) )
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ HANDLE hToken;
|
|
|
+ if(!GetTokenByName(hToken,_T("EXPLORER.EXE")))
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ STARTUPINFO si;
|
|
|
+ PROCESS_INFORMATION pi;
|
|
|
+
|
|
|
+ ZeroMemory(&si, sizeof(STARTUPINFO));
|
|
|
+ si.cb = sizeof(STARTUPINFO);
|
|
|
+ si.lpDesktop = TEXT("winsta0\\default");
|
|
|
+
|
|
|
+ BOOL bResult = CreateProcessAsUser(hToken,lpExePath,NULL,NULL,NULL, FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ CloseHandle(hToken);
|
|
|
+ if(bResult)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+#else
|
|
|
+ HANDLE hPtoken = NULL ;
|
|
|
+ GetExplorerToken( &hPtoken ) ;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ PROCESS_INFORMATION pi;
|
|
|
+ STARTUPINFOW si = { sizeof(STARTUPINFO),NULL,L"",NULL,0,0,0,0,0,0,0,STARTF_USESHOWWINDOW,0,0,NULL,0,0,0};
|
|
|
+ si.wShowWindow = SW_SHOW;
|
|
|
+ si.lpDesktop = NULL;
|
|
|
+ ZeroMemory( &pi, sizeof(pi) );
|
|
|
+
|
|
|
+ static HMODULE advapi32_dll = LoadLibraryW(L"advapi32.dll");
|
|
|
+ if(!advapi32_dll)
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+
|
|
|
+ GetProcAddress(advapi32_dll,"CreateProcessWithTokenW"));
|
|
|
+ if (f_CreateProcessWithTokenW == NULL)
|
|
|
+ return ;
|
|
|
+*/
|
|
|
+ BOOL bResult = CreateProcessWithTokenW(hPtoken, LOGON_WITH_PROFILE, NULL, (LPWSTR)lpExePath, NULL, NULL, NULL, &si,&pi);
|
|
|
+
|
|
|
+ DWORD dwError = GetLastError();
|
|
|
+ Sleep(1000);
|
|
|
+ CloseHandle( pi.hProcess );
|
|
|
+
|
|
|
+ CloseHandle( pi.hThread );
|
|
|
+#endif
|
|
|
+ return bResult;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BOOL GetTokenByName( IN HANDLE &hToken, IN LPCTSTR lpName)
|
|
|
+ {
|
|
|
+ if(!lpName)
|
|
|
+ {
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ BOOL bRet = FALSE;
|
|
|
+ HANDLE hProcessSnap = NULL;
|
|
|
+ PROCESSENTRY32 pe32 = {0};
|
|
|
+ hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
|
|
+ if ( hProcessSnap == INVALID_HANDLE_VALUE )
|
|
|
+ return FALSE;
|
|
|
+
|
|
|
+ pe32.dwSize = sizeof(PROCESSENTRY32);
|
|
|
+ if (Process32First(hProcessSnap, &pe32))
|
|
|
+ {
|
|
|
+ do
|
|
|
+ {
|
|
|
+ CString exefile=pe32.szExeFile;
|
|
|
+ CString paraname = lpName;
|
|
|
+ if(!exefile.CompareNoCase(lpName))
|
|
|
+ {
|
|
|
+ HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);
|
|
|
+ bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
|
|
|
+ CloseHandle( hProcessSnap );
|
|
|
+ return bRet;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ while(Process32Next(hProcessSnap,&pe32));
|
|
|
+ bRet = TRUE;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ bRet = FALSE;
|
|
|
+
|
|
|
+ CloseHandle(hProcessSnap);
|
|
|
+ return bRet;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ BOOL GetDebugPriv()
|
|
|
+ {
|
|
|
+
|
|
|
+ HANDLE hToken;
|
|
|
+
|
|
|
+ LUID sedebugnameValue;
|
|
|
+
|
|
|
+ TOKEN_PRIVILEGES tkp;
|
|
|
+ DWORD dwCurProcId = GetCurrentProcessId();
|
|
|
+
|
|
|
+ HANDLE hCurProc;
|
|
|
+ hCurProc = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwCurProcId);
|
|
|
+
|
|
|
+ if (!::OpenProcessToken(hCurProc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
|
|
+ {
|
|
|
+
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!::LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &sedebugnameValue))
|
|
|
+ {
|
|
|
+
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ tkp.PrivilegeCount = 1;
|
|
|
+ tkp.Privileges[0].Luid = sedebugnameValue;
|
|
|
+ tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
+
|
|
|
+ if (!::AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
|
|
|
+ {
|
|
|
+
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return FALSE;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle(hCurProc);
|
|
|
+ CloseHandle(hToken);
|
|
|
+ return TRUE;
|
|
|
+ }
|
|
|
+
|
|
|
+ DWORD GetExplorerToken(OUT HANDLE* phExplorerToken)
|
|
|
+ {
|
|
|
+ DWORD dwStatus = ERROR_FILE_NOT_FOUND ;
|
|
|
+ BOOL bRet = FALSE ;
|
|
|
+ HANDLE hProcess = NULL ;
|
|
|
+ HANDLE hProcessSnap = NULL ;
|
|
|
+ TCHAR szExplorerPath[MAX_PATH] = { 0 };
|
|
|
+ TCHAR FileName[MAX_PATH] = { 0 };
|
|
|
+ PROCESSENTRY32 pe32 = { 0 } ;
|
|
|
+ __try
|
|
|
+ {
|
|
|
+ GetWindowsDirectory( szExplorerPath , MAX_PATH ) ;
|
|
|
+ _tcscat_s( szExplorerPath , MAX_PATH, _T("\\Explorer.EXE") ) ;
|
|
|
+ hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 ) ;
|
|
|
+ if( hProcessSnap == INVALID_HANDLE_VALUE )
|
|
|
+ {
|
|
|
+ dwStatus = GetLastError() ;
|
|
|
+ __leave ;
|
|
|
+ }
|
|
|
+ pe32.dwSize = sizeof( PROCESSENTRY32 ) ;
|
|
|
+ if( !Process32First( hProcessSnap, &pe32 ))
|
|
|
+ {
|
|
|
+ dwStatus = GetLastError() ;
|
|
|
+ __leave ;
|
|
|
+ }
|
|
|
+
|
|
|
+ int ii = 0;
|
|
|
+ do
|
|
|
+ {
|
|
|
+ hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID ) ;
|
|
|
+ if( NULL != hProcess )
|
|
|
+ {
|
|
|
+ ii++;
|
|
|
+
|
|
|
+
|
|
|
+ if( _tcsicmp( pe32.szExeFile , _T("Explorer.EXE") ) == 0 )
|
|
|
+ {
|
|
|
+ HANDLE hToken ;
|
|
|
+ if( OpenProcessToken( hProcess , TOKEN_DUPLICATE , &hToken ))
|
|
|
+ {
|
|
|
+ HANDLE hNewToken = NULL;
|
|
|
+ DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &hNewToken);
|
|
|
+ * phExplorerToken = hNewToken ;
|
|
|
+ dwStatus = 0 ;
|
|
|
+ CloseHandle(hToken);
|
|
|
+ }
|
|
|
+ break ;
|
|
|
+ }
|
|
|
+
|
|
|
+ CloseHandle ( hProcess ) ;
|
|
|
+ hProcess = NULL ;
|
|
|
+ }
|
|
|
+
|
|
|
+ } while( Process32Next( hProcessSnap, &pe32 )) ;
|
|
|
+ }
|
|
|
+ __finally
|
|
|
+ {
|
|
|
+ if( NULL != hProcess )
|
|
|
+ {
|
|
|
+ CloseHandle( hProcess ) ;
|
|
|
+ }
|
|
|
+ if( NULL != hProcessSnap )
|
|
|
+ {
|
|
|
+ CloseHandle ( hProcessSnap ) ;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return dwStatus ;
|
|
|
+ }
|
|
|
+};
|