+int
+main(int argc, char *argv[])
+{
+ //DPRINT("tcpsvcs: main() started. See tcpsvcs_log.txt for info\n");
+
+ if (!StartServiceCtrlDispatcher(ServiceTable))
+ _tprintf(_T("failed to start the service control dispatcher\n"));
+
+ //DPRINT("tcpsvcs: main() done\n");
+
+ return 0;
+}
+
+
+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);
+
+ 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.dwCheckPoint = 0;
+ hServStatus.dwWaitHint = 2*CS_TIMEOUT;
+
+ hSStat = RegisterServiceCtrlHandler("tcpsvcs", ServerCtrlHandler);
+ if (hSStat == 0)
+ LogEvent(_T("Failed to register service\n"), 100, TRUE);
+
+ LogEvent(_T("Control handler registered successfully"), 0, FALSE);
+ SetServiceStatus (hSStat, &hServStatus);
+ LogEvent(_T("Service status set to SERVICE_START_PENDING"), 0, FALSE);
+
+ if (CreateServers() != 0)
+ {
+ hServStatus.dwCurrentState = SERVICE_STOPPED;
+ hServStatus.dwServiceSpecificExitCode = 1;
+ SetServiceStatus(hSStat, &hServStatus);
+ return;
+ }
+
+ LogEvent(_T("Service threads shut down. Set SERVICE_STOPPED status"), 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 */
+ return;
+
+}
+
+VOID WINAPI
+ServerCtrlHandler(DWORD Control)
+{
+ switch (Control)
+ {
+ case SERVICE_CONTROL_SHUTDOWN: /* fall through */
+ case SERVICE_CONTROL_STOP:
+ ShutDown = TRUE;
+ UpdateStatus(SERVICE_STOP_PENDING, -1);
+ break;
+ case SERVICE_CONTROL_PAUSE:
+ PauseFlag = TRUE;
+ break;
+ case SERVICE_CONTROL_CONTINUE:
+ PauseFlag = FALSE;
+ break;
+ case SERVICE_CONTROL_INTERROGATE:
+ break;
+ default:
+ if (Control > 127 && Control < 256) /* user defined */
+ break;
+ }
+ UpdateStatus(-1, -1); /* increment checkpoint */
+ return;
+}
+
+
+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);
+ return;
+}
+
+INT
+CreateServers()