ReactOS 0.4.15-dev-8138-g1e75ea8
tcpsvcs.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS simple TCP/IP services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/services/tcpsvcs/tcpsvcs.c
5 * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
6 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10#include "tcpsvcs.h"
11
12#include <winsvc.h>
13
14static WCHAR ServiceName[] = L"tcpsvcs";
15
16volatile BOOL bShutdown = FALSE;
17volatile BOOL bPause = FALSE;
18
19typedef struct _ServiceInfo
20{
24
25static SERVICES
27{
28 {ECHO_PORT, L"Echo", EchoHandler},
29 {DISCARD_PORT, L"Discard", DiscardHandler},
30 {DAYTIME_PORT, L"Daytime", DaytimeHandler},
31 {QOTD_PORT, L"QOTD", QotdHandler},
32 {CHARGEN_PORT, L"Chargen", ChargenHandler}
33};
34
35
36static VOID
38 DWORD NewStatus,
40{
41 WCHAR szSet[50];
42
43 if (Check > 0)
44 pServInfo->servStatus.dwCheckPoint += Check;
45 else
46 pServInfo->servStatus.dwCheckPoint = Check;
47
48 if (NewStatus > 0)
49 pServInfo->servStatus.dwCurrentState = NewStatus;
50
51 _snwprintf(szSet,
52 49,
53 L"Service state 0x%lx, CheckPoint %lu",
54 pServInfo->servStatus.dwCurrentState,
55 pServInfo->servStatus.dwCheckPoint);
56 LogEvent(szSet, 0, 0, LOG_FILE);
57
58 if (!SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus))
59 LogEvent(L"Cannot set service status", GetLastError(), 0, LOG_ALL);
60}
61
62
63static BOOL
65{
68 WSADATA wsaData;
69 WCHAR buf[256];
70 INT i;
71 DWORD RetVal;
72
73 if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
74 {
75 swprintf(buf, L"WSAStartup() failed : %lu\n", RetVal);
76 LogEvent(buf, 0, 100, LOG_ALL);
77 return FALSE;
78 }
79
80 UpdateStatus(pServInfo, 0, 1);
81
82 LogEvent(L"\nCreating server Threads", 0, 0, LOG_FILE);
83
84 /* Create worker threads. */
85 for (i = 0; i < NUM_SERVICES; i++)
86 {
87 swprintf(buf, L"Creating thread for %s server", Services[i].lpName);
88 LogEvent(buf, 0, 0, LOG_FILE);
89
91 0,
93 &Services[i],
94 0,
95 &dwThreadId[i]);
96
97 if (hThread[i] == NULL)
98 {
99 swprintf(buf, L"\nError creating %s server thread\n", Services[i].lpName);
101 return FALSE;
102 }
103
104 UpdateStatus(pServInfo, 0, 1);
105 }
106
107 LogEvent(L"Setting service status to running", 0, 0, LOG_FILE);
108 UpdateStatus(pServInfo, SERVICE_RUNNING, 0);
109
110 /* Wait until all threads have terminated. */
112
113 for (i = 0; i < NUM_SERVICES; i++)
114 {
115 if (hThread[i] != NULL)
117 }
118
119 LogEvent(L"Detaching Winsock2", 0, 0, LOG_FILE);
120 WSACleanup();
121
122 return TRUE;
123}
124
127 DWORD dwEventType,
128 LPVOID lpEventData,
129 LPVOID lpContext)
130{
131 PSERVICEINFO pServInfo = (PSERVICEINFO)lpContext;
132
133 switch (dwControl)
134 {
137 LogEvent(L"\nSetting the service to SERVICE_STOP_PENDING", 0, 0, LOG_FILE);
139 pServInfo->servStatus.dwWin32ExitCode = 0;
140 pServInfo->servStatus.dwWaitHint = 5000;
141 UpdateStatus(pServInfo, SERVICE_STOP_PENDING, 1);
142 break;
143
144 case SERVICE_CONTROL_PAUSE: /* not yet implemented */
145 LogEvent(L"Setting the service to SERVICE_PAUSED", 0, 0, LOG_FILE);
147 UpdateStatus(pServInfo, SERVICE_PAUSED, 0);
148 break;
149
151 LogEvent(L"Setting the service to SERVICE_RUNNING", 0, 0, LOG_FILE);
153 UpdateStatus(pServInfo, SERVICE_RUNNING, 0);
154 break;
155
157 SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus);
158 break;
159
160 default:
161 if (dwControl > 127 && dwControl < 256) /* user defined */
162 LogEvent(L"User defined control code", 0, 0, LOG_FILE);
163 else
164 LogEvent(L"ERROR: Bad control code", 0, 0, LOG_FILE);
165 break;
166 }
167}
168
171{
172 SERVICEINFO servInfo;
173
174 LogEvent(L"Entering ServiceMain.", 0, 0, LOG_FILE);
175
181 servInfo.servStatus.dwCheckPoint = 0;
182 servInfo.servStatus.dwWaitHint = 2 * CS_TIMEOUT;
183
184 LogEvent(L"Registering service control handler", 0, 0, LOG_FILE);
187 &servInfo);
188 if (!servInfo.hStatus)
189 LogEvent(L"Failed to register service", GetLastError(), 100, LOG_ALL);
190
191 UpdateStatus(&servInfo, SERVICE_START_PENDING, 1);
192
193 if (!CreateServers(&servInfo))
194 {
195 LogEvent(L"Error creating servers", GetLastError(), 1, LOG_ALL);
197 UpdateStatus(&servInfo, SERVICE_STOPPED, 0);
198 return;
199 }
200
201 LogEvent(L"Service threads shut down. Set SERVICE_STOPPED status", 0, 0, LOG_FILE);
202 UpdateStatus(&servInfo, SERVICE_STOPPED, 0);
203
204 LogEvent(L"Leaving ServiceMain\n", 0, 0, LOG_FILE);
205}
206
207
208int _tmain (int argc, LPTSTR argv [])
209{
211 {
213 {NULL, NULL }
214 };
215
216 if (InitLogging())
217 {
219 LogEvent(L"failed to start the service control dispatcher", GetLastError(), 101, LOG_ALL);
220
222 }
223
224 return 0;
225}
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
static int argc
Definition: ServiceArgs.c:12
#define InterlockedExchange
Definition: armddk.h:54
static SERVICE_TABLE_ENTRYW ServiceTable[2]
Definition: eventlog.c:24
VOID UninitLogging()
Definition: log.c:263
BOOL InitLogging()
Definition: log.c:210
VOID LogEvent(LPCWSTR lpMsg, DWORD errNum, DWORD exitCode, UINT flags)
Definition: log.c:196
DWORD WINAPI ChargenHandler(VOID *sock_)
Definition: chargen.c:96
DWORD WINAPI DaytimeHandler(VOID *Sock_)
Definition: daytime.c:29
DWORD WINAPI DiscardHandler(VOID *sock_)
Definition: discard.c:44
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
#define swprintf
Definition: precomp.h:40
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define INFINITE
Definition: serial.h:102
DWORD dwThreadId
Definition: fdebug.c:31
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _tmain
Definition: tchar.h:497
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
int Check()
Definition: movefile.cpp:196
#define argv
Definition: mplay32.c:18
HANDLE hThread
Definition: wizard.c:28
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
DWORD WINAPI QotdHandler(VOID *sock_)
Definition: qotd.c:135
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:812
BOOL WINAPI StartServiceCtrlDispatcherW(const SERVICE_TABLE_ENTRYW *lpServiceStartTable)
Definition: sctrl.c:1134
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:997
DWORD WINAPI EchoHandler(VOID *sock_)
Definition: echo.c:69
DWORD WINAPI StartServer(LPVOID lpParam)
Definition: skelserver.c:165
DWORD dwServiceType
Definition: winsvc.h:99
DWORD dwWin32ExitCode
Definition: winsvc.h:102
DWORD dwControlsAccepted
Definition: winsvc.h:101
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwCurrentState
Definition: winsvc.h:100
DWORD dwCheckPoint
Definition: winsvc.h:104
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
SERVICE_STATUS_HANDLE hStatus
Definition: tcpsvcs.c:22
SERVICE_STATUS servStatus
Definition: tcpsvcs.c:21
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
static WCHAR ServiceName[]
Definition: tcpsvcs.c:14
static SERVICES Services[NUM_SERVICES]
Definition: tcpsvcs.c:26
VOID WINAPI ServiceMain(DWORD argc, LPWSTR argv[])
Definition: tcpsvcs.c:170
struct _ServiceInfo SERVICEINFO
static VOID UpdateStatus(PSERVICEINFO pServInfo, DWORD NewStatus, DWORD Check)
Definition: tcpsvcs.c:37
volatile BOOL bShutdown
Definition: tcpsvcs.c:16
VOID WINAPI ServerCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
Definition: tcpsvcs.c:126
struct _ServiceInfo * PSERVICEINFO
static BOOL CreateServers(PSERVICEINFO pServInfo)
Definition: tcpsvcs.c:64
volatile BOOL bPause
Definition: tcpsvcs.c:17
#define DISCARD_PORT
Definition: tcpsvcs.h:21
#define QOTD_PORT
Definition: tcpsvcs.h:23
#define DAYTIME_PORT
Definition: tcpsvcs.h:22
#define LOG_ALL
Definition: tcpsvcs.h:17
#define ECHO_PORT
Definition: tcpsvcs.h:20
#define NUM_SERVICES
Definition: tcpsvcs.h:26
#define CS_TIMEOUT
Definition: tcpsvcs.h:27
#define CHARGEN_PORT
Definition: tcpsvcs.h:24
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
_In_ LPCSTR lpName
Definition: winbase.h:2789
#define WINAPI
Definition: msvc.h:6
#define ERROR_SERVICE_SPECIFIC_ERROR
Definition: winerror.h:617
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40
#define SERVICE_PAUSED
Definition: winsvc.h:27
DWORD(WINAPI * LPHANDLER_FUNCTION_EX)(DWORD, DWORD, LPVOID, LPVOID)
Definition: winsvc.h:191
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define SERVICE_ACCEPT_PAUSE_CONTINUE
Definition: winsvc.h:29
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
CHAR * LPTSTR
Definition: xmlstorage.h:192