1+ #include "collectd.h"
2+ #include <windows.h>
3+ #include <tchar.h>
4+
5+ #undef __CRT__NO_INLINE
6+ #include <strsafe.h>
7+ #define __CRT__NO_INLINE
8+
9+ #define SVC_ERROR 1
10+
11+ SERVICE_STATUS gSvcStatus ;
12+ SERVICE_STATUS_HANDLE gSvcStatusHandle ;
13+
14+ void WINAPI SvcCtrlHandler (DWORD );
15+ void WINAPI SvcMain (DWORD , LPTSTR * );
16+
17+ void ReportSvcStatus (DWORD , DWORD , DWORD );
18+ void SvcReportEvent (LPTSTR );
19+
20+ void __cdecl _tmain (int argc , TCHAR * argv []) {
21+ SERVICE_TABLE_ENTRY DispatchTable [] = {
22+ {PACKAGE_NAME , (LPSERVICE_MAIN_FUNCTION )SvcMain }, {NULL , NULL }};
23+
24+ if (!StartServiceCtrlDispatcher (DispatchTable )) {
25+ SvcReportEvent (TEXT ("StartServiceCtrlDispatcher" ));
26+ }
27+ }
28+
29+ int init (int argc , char * * argv ) {
30+ WORD wVersionRequested ;
31+ WSADATA wsaData ;
32+ int err ;
33+ wVersionRequested = MAKEWORD (2 , 2 );
34+
35+ err = WSAStartup (wVersionRequested , & wsaData );
36+ if (err != 0 ) {
37+ printf ("WSAStartup failed with error: %d\n" , err );
38+ SvcReportEvent (TEXT ("WSAStartup" ));
39+ return 1 ;
40+ }
41+
42+ struct cmdline_config config = init_config (argc , argv );
43+ return run_loop (config .test_readall );
44+ }
45+
46+ void WINAPI SvcMain (DWORD dwArgc , LPTSTR * lpszArgv ) {
47+ gSvcStatusHandle = RegisterServiceCtrlHandler (PACKAGE_NAME , SvcCtrlHandler );
48+
49+ if (!gSvcStatusHandle ) {
50+ SvcReportEvent (TEXT ("RegisterServiceCtrlHandler" ));
51+ return ;
52+ }
53+
54+ gSvcStatus .dwServiceType = SERVICE_WIN32_OWN_PROCESS ;
55+ gSvcStatus .dwServiceSpecificExitCode = 0 ;
56+ ReportSvcStatus (SERVICE_START_PENDING , NO_ERROR , 3000 );
57+ ReportSvcStatus (SERVICE_RUNNING , NO_ERROR , 0 );
58+ int err = init ((int )dwArgc , (char * * )lpszArgv );
59+ ReportSvcStatus (SERVICE_STOPPED , err , 0 );
60+ return ;
61+ }
62+
63+ /**
64+ * Sets the current service status and reports it to the SCM.
65+ * dwCurrentState - The current state (see SERVICE_STATUS)
66+ * dwWin32ExitCode - The system error code
67+ * dwWaitHint - Estimated time for pending operation,
68+ * in milliseconds
69+ */
70+ void ReportSvcStatus (DWORD dwCurrentState , DWORD dwWin32ExitCode ,
71+ DWORD dwWaitHint ) {
72+ static DWORD dwCheckPoint = 1 ;
73+
74+ gSvcStatus .dwCurrentState = dwCurrentState ;
75+ gSvcStatus .dwWin32ExitCode = dwWin32ExitCode ;
76+ gSvcStatus .dwWaitHint = dwWaitHint ;
77+
78+ if (dwCurrentState == SERVICE_START_PENDING )
79+ gSvcStatus .dwControlsAccepted = 0 ;
80+ else
81+ gSvcStatus .dwControlsAccepted = SERVICE_ACCEPT_STOP ;
82+
83+ if ((dwCurrentState == SERVICE_RUNNING ) ||
84+ (dwCurrentState == SERVICE_STOPPED ))
85+ gSvcStatus .dwCheckPoint = 0 ;
86+ else
87+ gSvcStatus .dwCheckPoint = dwCheckPoint ++ ;
88+
89+ SetServiceStatus (gSvcStatusHandle , & gSvcStatus );
90+ }
91+
92+ /**
93+ * Called by SCM whenever a control code is sent to the service
94+ * using the ControlService function.
95+ * dwCtrl - control code
96+ */
97+ void WINAPI SvcCtrlHandler (DWORD dwCtrl ) {
98+ switch (dwCtrl ) {
99+ case SERVICE_CONTROL_STOP :
100+ ReportSvcStatus (SERVICE_STOP_PENDING , NO_ERROR , 0 );
101+ stop_collectd ();
102+ ReportSvcStatus (gSvcStatus .dwCurrentState , NO_ERROR , 0 );
103+ return ;
104+ case SERVICE_CONTROL_INTERROGATE :
105+ break ;
106+ default :
107+ break ;
108+ }
109+ }
110+
111+ /**
112+ * Logs messages to the event log. The service must
113+ * have an entry in the Application event log.
114+ * szFunction - name of function that failed
115+ */
116+ VOID SvcReportEvent (LPTSTR szFunction ) {
117+ HANDLE hEventSource ;
118+ LPCTSTR lpszStrings [2 ];
119+ TCHAR Buffer [80 ];
120+
121+ hEventSource = RegisterEventSource (NULL , PACKAGE_NAME );
122+
123+ if (NULL != hEventSource ) {
124+ StringCchPrintf (Buffer , 80 , TEXT ("%s failed with %d" ), szFunction ,
125+ GetLastError ());
126+
127+ lpszStrings [0 ] = PACKAGE_NAME ;
128+ lpszStrings [1 ] = Buffer ;
129+
130+ ReportEvent (hEventSource , // event log handle
131+ EVENTLOG_ERROR_TYPE , // event type
132+ 0 , // event category
133+ SVC_ERROR , // event identifier
134+ NULL , // no security identifier
135+ 2 , // size of lpszStrings array
136+ 0 , // no binary data
137+ lpszStrings , // array of strings
138+ NULL ); // no binary data
139+
140+ DeregisterEventSource (hEventSource );
141+ }
142+ }
0 commit comments