X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Fapps%2Futils%2Fnet%2Ftcpsvcs%2Ftcpsvcs.c;h=1d5cc92d2b535d83ff1b70882f05196af42988ff;hp=3db7aadf6cc7adabcf4e461b5e6da61e83dd56e9;hb=0b7743d63e1b690ad843782dae1f7305345b1f2d;hpb=b9430af2fdbd1b98305f3de5b1599784aecc33d1 diff --git a/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c b/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c index 3db7aadf6cc..1d5cc92d2b5 100644 --- a/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c +++ b/reactos/apps/utils/net/tcpsvcs/tcpsvcs.c @@ -3,68 +3,67 @@ #include #include "tcpsvcs.h" -static -LPTHREAD_START_ROUTINE -ServiceHandler[NUM_SERVICES] = -{ - EchoHandler, - DiscardHandler, - DaytimeHandler, - QotdHandler, - ChargenHandler -}; - -static int -ServicePort[NUM_SERVICES] = -{ - ECHO_PORT, - DISCARD_PORT, - DAYTIME_PORT, - QOTD_PORT, - CHARGEN_PORT -}; - #if 0 -static -SERVICE_TABLE_ENTRY +/* + * globals + */ +static SERVICE_STATUS hServStatus; +static SERVICE_STATUS_HANDLE hSStat; +FILE *hLogFile; +BOOL bLogEvents = TRUE; +BOOL ShutDown, PauseFlag; +LPTSTR LogFileName = "tcpsvcs_log.txt"; + +static SERVICE_TABLE_ENTRY ServiceTable[2] = { - {TEXT("tcpsvcs"), ServiceMain}, + {_T("tcpsvcs"), ServiceMain}, {NULL, NULL} }; #endif +static SERVICES +Services[NUM_SERVICES] = +{ + {ECHO_PORT, _T("Echo"), EchoHandler}, + {DISCARD_PORT, _T("Discard"), DiscardHandler}, + {DAYTIME_PORT, _T("Daytime"), DaytimeHandler}, + {QOTD_PORT, _T("QOTD"), QotdHandler}, + {CHARGEN_PORT, _T("Chargen"), ChargenHandler} +}; + + int main(void) { - PSERVICES pServices[NUM_SERVICES]; DWORD dwThreadId[NUM_SERVICES]; HANDLE hThread[NUM_SERVICES]; + WSADATA wsaData; + DWORD RetVal; INT i; + if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) + { + _tprintf(_T("WSAStartup() failed : %lu\n"), RetVal); + return -1; + } + /* Create MAX_THREADS worker threads. */ for( i=0; iService = ServiceHandler[i]; - pServices[i]->Port = ServicePort[i]; + _tprintf(_T("Starting %s server....\n"), Services[i].Name); hThread[i] = CreateThread( NULL, // default security attributes 0, // use default stack size StartServer, // thread function - pServices[i], // argument to thread function + &Services[i], // argument to thread function 0, // use default creation flags &dwThreadId[i]); // returns the thread identifier /* Check the return value for success. */ if (hThread[i] == NULL) { + _tprintf(_T("Failed to start %s server....\n"), Services[i].Name); ExitProcess(i); } } @@ -80,39 +79,134 @@ int main(void) return 0; } + + +/* code to run tcpsvcs as a service */ #if 0 -static VOID CALLBACK -ServiceMain(DWORD argc, LPTSTR *argv) +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() { - PSERVICES pServices[NUM_SERVICES]; DWORD dwThreadId[NUM_SERVICES]; HANDLE hThread[NUM_SERVICES]; INT i; + UpdateStatus(-1, -1); /* increment checkpoint */ + /* Create MAX_THREADS worker threads. */ for( i=0; iService = ServiceHandler[i]; - pServices[i]->Port = ServicePort[i]; + _tprintf(_T("Starting %s server....\n"), Services[i].Name); hThread[i] = CreateThread( NULL, // default security attributes 0, // use default stack size StartServer, // thread function - pServices[i], // argument to thread function + &Services[i], // argument to thread function 0, // use default creation flags &dwThreadId[i]); // returns the thread identifier /* Check the return value for success. */ if (hThread[i] == NULL) { + _tprintf(_T("Failed to start %s server....\n"), Services[i].Name); ExitProcess(i); } } @@ -125,20 +219,42 @@ ServiceMain(DWORD argc, LPTSTR *argv) { CloseHandle(hThread[i]); } - + return 0; } -int -main(int argc, char *argv[]) + +/* 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. */ +VOID +LogEvent (LPCTSTR UserMessage, DWORD ExitCode, BOOL PrintErrorMsg) { - DPRINT("tcpsvcs: main() started\n"); + DWORD eMsgLen, ErrNum = GetLastError (); + LPTSTR lpvSysMsg; + TCHAR MessageBuffer[512]; - StartServiceCtrlDispatcher(ServiceTable); + if (PrintErrorMsg) { + eMsgLen = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, NULL, + ErrNum, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpvSysMsg, 0, NULL); - DPRINT("Umpnpmgr: main() done\n"); + _stprintf (MessageBuffer, _T("\n%s %s ErrNum = %d. ExitCode = %d."), + UserMessage, lpvSysMsg, ErrNum, ExitCode); + HeapFree (GetProcessHeap (), 0, lpvSysMsg); + /* Explained in Chapter 6. */ + } else { + _stprintf (MessageBuffer, _T("\n%s ExitCode = %d."), + UserMessage, ExitCode); + } - ExitThread(0); + fputs (MessageBuffer, hLogFile); - return 0; + if (ExitCode > 0) + ExitProcess (ExitCode); + else + return; } + #endif