ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tcpsvcs.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.