Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentcpsvcs.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS simple TCP/IP services 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: /base/services/tcpsvcs/tcpsvcs.c 00005 * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services 00006 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@reactos.org> 00007 * 00008 */ 00009 00010 #include "tcpsvcs.h" 00011 00012 static WCHAR ServiceName[] = L"tcpsvcs"; 00013 00014 volatile BOOL bShutdown = FALSE; 00015 volatile BOOL bPause = FALSE; 00016 00017 typedef struct _ServiceInfo 00018 { 00019 SERVICE_STATUS servStatus; 00020 SERVICE_STATUS_HANDLE hStatus; 00021 } SERVICEINFO, *PSERVICEINFO; 00022 00023 static SERVICES 00024 Services[NUM_SERVICES] = 00025 { 00026 {ECHO_PORT, L"Echo", EchoHandler}, 00027 {DISCARD_PORT, L"Discard", DiscardHandler}, 00028 {DAYTIME_PORT, L"Daytime", DaytimeHandler}, 00029 {QOTD_PORT, L"QOTD", QotdHandler}, 00030 {CHARGEN_PORT, L"Chargen", ChargenHandler} 00031 }; 00032 00033 00034 static VOID 00035 UpdateStatus(PSERVICEINFO pServInfo, 00036 DWORD NewStatus, 00037 DWORD Check) 00038 { 00039 WCHAR szSet[50]; 00040 00041 if (Check > 0) 00042 pServInfo->servStatus.dwCheckPoint += Check; 00043 else 00044 pServInfo->servStatus.dwCheckPoint = Check; 00045 00046 if (NewStatus > 0) 00047 pServInfo->servStatus.dwCurrentState = NewStatus; 00048 00049 _snwprintf(szSet, 00050 49, 00051 L"Service state 0x%lu, CheckPoint %lu", 00052 pServInfo->servStatus.dwCurrentState, 00053 pServInfo->servStatus.dwCheckPoint); 00054 LogEvent(szSet, 0, 0, LOG_FILE); 00055 00056 if (!SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus)) 00057 LogEvent(L"Cannot set service status", GetLastError(), 0, LOG_ALL); 00058 } 00059 00060 00061 static BOOL 00062 CreateServers(PSERVICEINFO pServInfo) 00063 { 00064 DWORD dwThreadId[NUM_SERVICES]; 00065 HANDLE hThread[NUM_SERVICES]; 00066 WSADATA wsaData; 00067 WCHAR buf[256]; 00068 INT i; 00069 DWORD RetVal; 00070 00071 if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) 00072 { 00073 _swprintf(buf, L"WSAStartup() failed : %lu\n", RetVal); 00074 LogEvent(buf, 0, 100, LOG_ALL); 00075 return FALSE; 00076 } 00077 00078 UpdateStatus(pServInfo, 0, 1); 00079 00080 LogEvent(L"\nCreating server Threads", 0, 0, LOG_FILE); 00081 00082 /* Create worker threads. */ 00083 for (i = 0; i < NUM_SERVICES; i++) 00084 { 00085 _swprintf(buf, L"Creating thread for %s server", Services[i].lpName); 00086 LogEvent(buf, 0, 0, LOG_FILE); 00087 00088 hThread[i] = CreateThread(NULL, 00089 0, 00090 StartServer, 00091 &Services[i], 00092 0, 00093 &dwThreadId[i]); 00094 00095 if (hThread[i] == NULL) 00096 { 00097 _swprintf(buf, L"\nError creating %s server thread\n", Services[i].lpName); 00098 LogEvent(buf, GetLastError(), 0, LOG_ALL); 00099 return FALSE; 00100 } 00101 00102 UpdateStatus(pServInfo, 0, 1); 00103 } 00104 00105 LogEvent(L"Setting service status to running", 0, 0, LOG_FILE); 00106 UpdateStatus(pServInfo, SERVICE_RUNNING, 0); 00107 00108 /* Wait until all threads have terminated. */ 00109 WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE); 00110 00111 for (i = 0; i < NUM_SERVICES; i++) 00112 { 00113 if (hThread[i] != NULL) 00114 CloseHandle(hThread[i]); 00115 } 00116 00117 LogEvent(L"Detaching Winsock2", 0, 0, LOG_FILE); 00118 WSACleanup(); 00119 00120 return TRUE; 00121 } 00122 00123 VOID WINAPI 00124 ServerCtrlHandler(DWORD dwControl, 00125 DWORD dwEventType, 00126 LPVOID lpEventData, 00127 LPVOID lpContext) 00128 { 00129 PSERVICEINFO pServInfo = (PSERVICEINFO)lpContext; 00130 00131 switch (dwControl) 00132 { 00133 case SERVICE_CONTROL_SHUTDOWN: 00134 case SERVICE_CONTROL_STOP: 00135 LogEvent(L"\nSetting the service to SERVICE_STOP_PENDING", 0, 0, LOG_FILE); 00136 InterlockedExchange((LONG *)&bShutdown, TRUE); 00137 pServInfo->servStatus.dwWin32ExitCode = 0; 00138 pServInfo->servStatus.dwWaitHint = 5000; 00139 UpdateStatus(pServInfo, SERVICE_STOP_PENDING, 1); 00140 break; 00141 00142 case SERVICE_CONTROL_PAUSE: /* not yet implemented */ 00143 LogEvent(L"Setting the service to SERVICE_PAUSED", 0, 0, LOG_FILE); 00144 InterlockedExchange((LONG *)&bPause, TRUE); 00145 UpdateStatus(pServInfo, SERVICE_PAUSED, 0); 00146 break; 00147 00148 case SERVICE_CONTROL_CONTINUE: 00149 LogEvent(L"Setting the service to SERVICE_RUNNING", 0, 0, LOG_FILE); 00150 InterlockedExchange((LONG *)&bPause, FALSE); 00151 UpdateStatus(pServInfo, SERVICE_RUNNING, 0); 00152 break; 00153 00154 case SERVICE_CONTROL_INTERROGATE: 00155 SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus); 00156 break; 00157 00158 default: 00159 if (dwControl > 127 && dwControl < 256) /* user defined */ 00160 LogEvent(L"User defined control code", 0, 0, LOG_FILE); 00161 else 00162 LogEvent(L"ERROR: Bad control code", 0, 0, LOG_FILE); 00163 break; 00164 } 00165 } 00166 00167 VOID WINAPI 00168 ServiceMain(DWORD argc, LPWSTR argv[]) 00169 { 00170 SERVICEINFO servInfo; 00171 00172 LogEvent(L"Entering ServiceMain.", 0, 0, LOG_FILE); 00173 00174 servInfo.servStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 00175 servInfo.servStatus.dwCurrentState = SERVICE_STOPPED; 00176 servInfo.servStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE; 00177 servInfo.servStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR; 00178 servInfo.servStatus.dwServiceSpecificExitCode = 0; 00179 servInfo.servStatus.dwCheckPoint = 0; 00180 servInfo.servStatus.dwWaitHint = 2 * CS_TIMEOUT; 00181 00182 LogEvent(L"Registering service control handler", 0, 0, LOG_FILE); 00183 servInfo.hStatus = RegisterServiceCtrlHandlerExW(ServiceName, 00184 (LPHANDLER_FUNCTION_EX)ServerCtrlHandler, 00185 &servInfo); 00186 if (!servInfo.hStatus) 00187 LogEvent(L"Failed to register service", GetLastError(), 100, LOG_ALL); 00188 00189 UpdateStatus(&servInfo, SERVICE_START_PENDING, 1); 00190 00191 if (!CreateServers(&servInfo)) 00192 { 00193 LogEvent(L"Error creating servers", GetLastError(), 1, LOG_ALL); 00194 servInfo.servStatus.dwServiceSpecificExitCode = 1; 00195 UpdateStatus(&servInfo, SERVICE_STOPPED, 0); 00196 return; 00197 } 00198 00199 LogEvent(L"Service threads shut down. Set SERVICE_STOPPED status", 0, 0, LOG_FILE); 00200 UpdateStatus(&servInfo, SERVICE_STOPPED, 0); 00201 00202 LogEvent(L"Leaving ServiceMain\n", 0, 0, LOG_FILE); 00203 } 00204 00205 00206 int _tmain (int argc, LPTSTR argv []) 00207 { 00208 SERVICE_TABLE_ENTRYW ServiceTable[] = 00209 { 00210 {ServiceName, ServiceMain}, 00211 {NULL, NULL } 00212 }; 00213 00214 if (InitLogging()) 00215 { 00216 if (!StartServiceCtrlDispatcherW(ServiceTable)) 00217 LogEvent(L"failed to start the service control dispatcher", GetLastError(), 101, LOG_ALL); 00218 00219 UninitLogging(); 00220 } 00221 00222 return 0; 00223 } Generated on Sun May 27 2012 04:17:54 for ReactOS by
1.7.6.1
|