eliminate GCC warning about initialization order
[reactos.git] / reactos / services / tcpsvcs / tcpsvcs.c
index 014fcde..809cc05 100644 (file)
  */
 /*
  * TODO:
- * - Start tcpsvcs as a service.
- * - write debugging function and print all dbg info via that.
- *
+ * - fix bug when terminating chargen server
+ * - log info in the event logger (when it's implemented)
  */
-#include <stdio.h>
-#include <winsock2.h>
-#include <tchar.h>
+
+
 #include "tcpsvcs.h"
 
-#if 0
+//#define NDEBUG
+//#include <debug.h>
+
+
 /*
  * globals
  */
+VOID WINAPI ServiceMain(DWORD argc, LPTSTR argv[]);
+
 static SERVICE_STATUS hServStatus;
 static SERVICE_STATUS_HANDLE hSStat;
+
 FILE *hLogFile;
-BOOL bLogEvents = TRUE;
-BOOL ShutDown, PauseFlag;
-LPCTSTR LogFileName = "tcpsvcs_log.log";
+BOOL bShutDown = FALSE;
+BOOL bPause = FALSE;
 
-static SERVICE_TABLE_ENTRY
-ServiceTable[2] =
-{
-    {_T("tcpsvcs"), ServiceMain},
-    {NULL, NULL}
-};
-#endif
+LPCTSTR LogFileName = "\\tcpsvcs_log.log";
+LPTSTR ServiceName = _T("Simp Tcp");
+//LPTSTR DisplayName = _T("Simple TCP/IP Services");
 
 static SERVICES
 Services[NUM_SERVICES] =
@@ -53,97 +51,65 @@ Services[NUM_SERVICES] =
 };
 
 
-int main(void)
+int
+main(void)
 {
-    DWORD dwThreadId[NUM_SERVICES];
-    HANDLE hThread[NUM_SERVICES];
-    WSADATA wsaData;
-    DWORD RetVal;
-    INT i;
-    
-    if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
+    SERVICE_TABLE_ENTRY ServiceTable[] =
     {
-        _tprintf(_T("WSAStartup() failed : %lu\n"), RetVal);
-        return -1;
-    }
+        {ServiceName, ServiceMain},
+        {NULL, NULL}
+    };
 
-    /* Create MAX_THREADS worker threads. */
-    for( i=0; i<NUM_SERVICES; i++ )
-    {
-        _tprintf(_T("Starting %s server....\n"), Services[i].Name);
+    //DPRINT("Starting tcpsvcs service. See \system32%s for logs\n", LogFileName);
 
-        hThread[i] = CreateThread(
-            NULL,              // default security attributes
-            0,                 // use default stack size
-            StartServer,       // thread function
-            &Services[i],     // argument to thread function
-            0,                 // use default creation flags
-            &dwThreadId[i]);   // returns the thread identifier
+    if (! StartServiceCtrlDispatcher(ServiceTable))
+        LogEvent(_T("failed to start the service control dispatcher\n"), -1, TRUE);
 
-        /* Check the return value for success. */
-        if (hThread[i] == NULL)
-        {
-            _tprintf(_T("Failed to start %s server....\n"), Services[i].Name);
-            //ExitProcess(i);
-        }
-    }
+    //DPRINT("Shutdown tcpsvcs service\n");
 
-    /* Wait until all threads have terminated. */
-    WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE);
-
-    /* Close all thread handles upon completion. */
-    for(i=0; i<NUM_SERVICES; i++)
-    {
-        CloseHandle(hThread[i]);
-    }
     return 0;
 }
 
 
-
-/* code to run tcpsvcs as a service through services.msc */
-#if 0
-int
-main(int argc, char *argv[])
+VOID WINAPI
+ServiceMain(DWORD argc, LPTSTR argv[])
 {
-    //DPRINT("tcpsvcs: main() started. See tcpsvcs_log.txt for info\n");
+       TCHAR LogFilePath[MAX_PATH];
 
-    if (!StartServiceCtrlDispatcher(ServiceTable))
-        _tprintf(_T("failed to start the service control dispatcher\n"));
+    if(! GetSystemDirectory(LogFilePath, MAX_PATH))
+        return;
 
-    //DPRINT("tcpsvcs: main() done\n");
+    _tcscat(LogFilePath, LogFileName);
 
-    return 0;
-}
+       hLogFile = fopen(LogFilePath, _T("a+"));
+    if (hLogFile == NULL)
+    {
+        TCHAR buf[50];
 
+        _stprintf(buf, _T("Could not open log file: %s\n"), LogFilePath);
+        MessageBox(NULL, buf, NULL, MB_OK);
+        return;
+    }
 
-static VOID WINAPI
-ServiceMain(DWORD argc, LPTSTR argv[])
-{
-    DWORD i;
 
-    hLogFile = fopen(LogFileName, _T("w+"));
-    if (hLogFile == NULL)
-        return;
-        
-    LogEvent(_T("Entering ServiceMain"), 0, FALSE);
+    LogEvent(_T("Entering ServiceMain\n"), 0, FALSE);
 
     hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
     hServStatus.dwCurrentState = SERVICE_START_PENDING;
     hServStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
         SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;
     hServStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
-    hServStatus.dwServiceSpecificExitCode = 0;
+    hServStatus.dwServiceSpecificExitCode = NO_ERROR;
     hServStatus.dwCheckPoint = 0;
     hServStatus.dwWaitHint = 2*CS_TIMEOUT;
-    
-    hSStat = RegisterServiceCtrlHandler("tcpsvcs", ServerCtrlHandler);
+
+    hSStat = RegisterServiceCtrlHandler(ServiceName, ServerCtrlHandler);
     if (hSStat == 0)
-        LogEvent(_T("Failed to register service\n"), 100, TRUE);
+        LogEvent(_T("Failed to register service\n"), -1, TRUE);
 
-       LogEvent(_T("Control handler registered successfully"), 0, FALSE);
+       LogEvent(_T("Control handler registered successfully\n"), 0, FALSE);
        SetServiceStatus (hSStat, &hServStatus);
-       LogEvent(_T("Service status set to SERVICE_START_PENDING"), 0, FALSE);
+       LogEvent(_T("Service status set to SERVICE_START_PENDING\n"), 0, FALSE);
 
     if (CreateServers() != 0)
     {
@@ -152,13 +118,16 @@ ServiceMain(DWORD argc, LPTSTR argv[])
         SetServiceStatus(hSStat, &hServStatus);
         return;
     }
-    
-       LogEvent(_T("Service threads shut down. Set SERVICE_STOPPED status"), 0, FALSE);
+
+       LogEvent(_T("Service threads shut down. Set SERVICE_STOPPED status\n"), 0, FALSE);
        /*  We will only return here when the ServiceSpecific function
                completes, indicating system shutdown. */
        UpdateStatus (SERVICE_STOPPED, 0);
-       LogEvent(_T("Service status set to SERVICE_STOPPED"), 0, FALSE);
-       fclose(hLogFile);  /*  Clean up everything, in general */
+       LogEvent(_T("Service status set to SERVICE_STOPPED\n"), 0, FALSE);
+       LogEvent(_T("Leaving ServiceMain\n"), 0, FALSE);
+       
+       fclose(hLogFile);
+
        return;
 
 }
@@ -170,14 +139,17 @@ ServerCtrlHandler(DWORD Control)
     {
         case SERVICE_CONTROL_SHUTDOWN: /* fall through */
         case SERVICE_CONTROL_STOP:
-            ShutDown = TRUE;
+                       LogEvent(_T("stopping service\n"), 0, FALSE);
+            InterlockedExchange((LONG *)&bShutDown, TRUE);
             UpdateStatus(SERVICE_STOP_PENDING, -1);
             break;
-        case SERVICE_CONTROL_PAUSE:
-            PauseFlag = TRUE;
+        case SERVICE_CONTROL_PAUSE: /* not yet implemented */
+                       LogEvent(_T("pausing service\n"), 0, FALSE);
+            InterlockedExchange((LONG *)&bPause, TRUE);
             break;
         case SERVICE_CONTROL_CONTINUE:
-            PauseFlag = FALSE;
+                       LogEvent(_T("continuing service\n"), 0, FALSE);
+            InterlockedExchange((LONG *)&bPause, FALSE);
             break;
         case SERVICE_CONTROL_INTERROGATE:
             break;
@@ -193,11 +165,17 @@ ServerCtrlHandler(DWORD Control)
 void UpdateStatus (int NewStatus, int Check)
 /*  Set a new service status and checkpoint (either specific value or increment) */
 {
-       if (Check < 0 ) hServStatus.dwCheckPoint++;
-       else                    hServStatus.dwCheckPoint = Check;
-       if (NewStatus >= 0) hServStatus.dwCurrentState = NewStatus;
-       if (!SetServiceStatus (hSStat, &hServStatus))
-               LogEvent (_T("Cannot set service status"), 101, TRUE);
+       if (Check < 0 )
+        hServStatus.dwCheckPoint++;
+       else
+        hServStatus.dwCheckPoint = Check;
+
+       if (NewStatus >= 0)
+        hServStatus.dwCurrentState = NewStatus;
+
+       if (! SetServiceStatus (hSStat, &hServStatus))
+               LogEvent(_T("Cannot set service status\n"), -1, TRUE);
+
        return;
 }
 
@@ -206,14 +184,27 @@ CreateServers()
 {
     DWORD dwThreadId[NUM_SERVICES];
     HANDLE hThread[NUM_SERVICES];
+       WSADATA wsaData;
+       TCHAR buf[256];
     INT i;
-    
+    DWORD RetVal;
+
+    if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
+    {
+        _stprintf(buf, _T("WSAStartup() failed : %lu\n"), RetVal);
+        LogEvent(buf, RetVal, TRUE);
+        return -1;
+    }
+
     UpdateStatus(-1, -1); /* increment checkpoint */
 
+    LogEvent(_T("Creating server Threads\n"), 0, FALSE);
+
     /* Create MAX_THREADS worker threads. */
     for( i=0; i<NUM_SERVICES; i++ )
     {
-        _tprintf(_T("Starting %s server....\n"), Services[i].Name);
+        _stprintf(buf, _T("Starting %s server....\n"), Services[i].Name);
+        LogEvent(buf, 0, FALSE);
 
         hThread[i] = CreateThread(
             NULL,              // default security attributes
@@ -226,11 +217,18 @@ CreateServers()
         /* Check the return value for success. */
         if (hThread[i] == NULL)
         {
-            _tprintf(_T("Failed to start %s server....\n"), Services[i].Name);
+            _stprintf(buf, _T("Failed to start %s server....\n"), Services[i].Name);
+            /* don't exit process via LogEvent. We want to exit via the server
+             * which failed to start, which could mean i=0 */
+            LogEvent(buf, 0, TRUE);
             ExitProcess(i);
         }
     }
 
+    LogEvent(_T("setting service status to running\n"), 0, FALSE);
+
+    UpdateStatus(SERVICE_RUNNING, 0);
+
     /* Wait until all threads have terminated. */
     WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE);
 
@@ -239,41 +237,45 @@ CreateServers()
     {
         CloseHandle(hThread[i]);
     }
+    
+    LogEvent(_T("Detaching Winsock2...\n"), 0, FALSE);
+    WSACleanup();
+    
     return 0;
 }
 
 
-/*     LogEvent is similar to the ReportError function used elsewhere
-       For a service, however, we ReportEvent rather than write to standard
-       error. Eventually, this function should go into the utility
-       library.  */
+/*     This is a temperary log system until our eventlog is in place  */
+
 VOID
-LogEvent (LPCTSTR UserMessage, DWORD ExitCode, BOOL PrintErrorMsg)
+LogEvent (LPCTSTR UserMessage, INT ExitCode, BOOL PrintErrorMsg)
 {
        DWORD eMsgLen, ErrNum = GetLastError ();
        LPTSTR lpvSysMsg;
        TCHAR MessageBuffer[512];
 
-       if (PrintErrorMsg) {
+
+
+       if (PrintErrorMsg)
+    {
                eMsgLen = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
                        FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                        ErrNum, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
                        (LPTSTR)&lpvSysMsg, 0, NULL);
 
-               _stprintf (MessageBuffer, _T("\n%s %s ErrNum = %d. ExitCode = %d."),
+               _stprintf(MessageBuffer, _T("%s %s ErrNum = %lu. ExitCode = %d."),
                        UserMessage, lpvSysMsg, ErrNum, ExitCode);
-               HeapFree (GetProcessHeap (), 0, lpvSysMsg);
-       } else {
-               _stprintf (MessageBuffer, _T("\n%s ExitCode = %d."),
-                       UserMessage, ExitCode);
+               HeapFree(GetProcessHeap (), 0, lpvSysMsg);
+       }
+    else
+    {
+               _stprintf(MessageBuffer, _T("%s"), UserMessage);
        }
 
        fputs (MessageBuffer, hLogFile);
 
-       if (ExitCode > 0)
-               ExitProcess (ExitCode);
+       if (ExitCode != 0)
+               ExitProcess(ExitCode);
        else
                return;
 }
-
-#endif