mirror of
https://github.com/reactos/reactos.git
synced 2024-12-26 00:54:40 +00:00
-Start to convert tcpsvcs to a proper NT service. Supports starting and stopping via sc.exe (in windows, not working in ROS yet)
- use select to make accept non-blocking - Log all data to a log file in system32. This needs converting to the event logger at some time. - Add more error checking -A few bugs to iron out yet svn path=/trunk/; revision=19151
This commit is contained in:
parent
b4b9ed3504
commit
50d1415ee4
8 changed files with 243 additions and 187 deletions
|
@ -24,20 +24,20 @@ DWORD WINAPI ChargenHandler(VOID* Sock_)
|
|||
|
||||
if (!GenerateChars(Sock))
|
||||
{
|
||||
_tprintf(_T("Char generation failed\n"));
|
||||
LogEvent(_T("Chargen: Char generation failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Shutting connection down...\n"));
|
||||
LogEvent(_T("Chargen: Shutting connection down...\n"), 0, FALSE);
|
||||
if (ShutdownConnection(Sock, FALSE))
|
||||
_tprintf(_T("Connection is down.\n"));
|
||||
LogEvent(_T("Chargen: Connection is down.\n"), 0, FALSE);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("Connection shutdown failed\n"));
|
||||
LogEvent(_T("Chargen: Connection shutdown failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Terminating chargen thread\n"));
|
||||
LogEvent(_T("Chargen: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(RetVal);
|
||||
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ BOOL SendLine(SOCKET Sock, TCHAR* Line)
|
|||
{
|
||||
if (RetVal != LineSize)
|
||||
{
|
||||
_tprintf(("Not sent enough\n"));
|
||||
LogEvent(_T("Chargen: Not sent enough bytes\n"), 0, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
SentBytes += RetVal;
|
||||
|
@ -116,13 +116,13 @@ BOOL SendLine(SOCKET Sock, TCHAR* Line)
|
|||
}
|
||||
else if (RetVal == SOCKET_ERROR)
|
||||
{
|
||||
_tprintf(("Socket error\n"));
|
||||
LogEvent(_T("Chargen: Socket error\n"), 0, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
_tprintf(("unknown error\n"));
|
||||
LogEvent(_T("Chargen: unknown error\n"), 0, FALSE);
|
||||
//WSAGetLastError()
|
||||
|
||||
_tprintf(("Connection closed by peer.\n"));
|
||||
LogEvent(_T("Chargen: Connection closed by peer.\n"), 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -32,16 +32,16 @@ DWORD WINAPI DaytimeHandler(VOID* Sock_)
|
|||
|
||||
SendTime(Sock, pszTime);
|
||||
|
||||
_tprintf(_T("Shutting connection down...\n"));
|
||||
LogEvent(_T("DayTime: Shutting connection down...\n"), 0, FALSE);
|
||||
if (ShutdownConnection(Sock, FALSE))
|
||||
_tprintf(_T("Connection is down.\n"));
|
||||
LogEvent(_T("DayTime: Connection is down.\n"), 0, FALSE);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("Connection shutdown failed\n"));
|
||||
LogEvent(_T("DayTime: Connection shutdown failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Terminating daytime thread\n"));
|
||||
LogEvent(_T("DayTime: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(RetVal);
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,6 @@ BOOL SendTime(SOCKET Sock, TCHAR *time)
|
|||
if (RetVal == SOCKET_ERROR)
|
||||
return FALSE;
|
||||
|
||||
_tprintf(("Connection closed by peer.\n"));
|
||||
LogEvent(_T("DayTime: Connection closed by peer.\n"), 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winsock2.h>
|
||||
#include <tchar.h>
|
||||
#include "tcpsvcs.h"
|
||||
|
||||
DWORD WINAPI DiscardHandler(VOID* Sock_)
|
||||
|
@ -24,22 +21,20 @@ DWORD WINAPI DiscardHandler(VOID* Sock_)
|
|||
|
||||
if (!RecieveIncomingPackets(Sock))
|
||||
{
|
||||
_tprintf(_T("RecieveIncomingPackets failed\n"));
|
||||
LogEvent(_T("Discard: RecieveIncomingPackets failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Shutting connection down...\n"));
|
||||
LogEvent(_T("Discard: Shutting connection down...\n"), 0, FALSE);
|
||||
if (ShutdownConnection(Sock, TRUE))
|
||||
{
|
||||
_tprintf(_T("Connection is down.\n"));
|
||||
}
|
||||
LogEvent(_T("Discard: Connection is down.\n"), 0, FALSE);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("Connection shutdown failed\n"));
|
||||
LogEvent(_T("Discard: Connection shutdown failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Terminating discard thread\n"));
|
||||
LogEvent(_T("Discard: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(RetVal);
|
||||
}
|
||||
|
||||
|
@ -48,20 +43,25 @@ DWORD WINAPI DiscardHandler(VOID* Sock_)
|
|||
BOOL RecieveIncomingPackets(SOCKET Sock)
|
||||
{
|
||||
TCHAR ReadBuffer[BUF];
|
||||
TCHAR temp[512]; // temp for holding LogEvent text
|
||||
INT ReadBytes;
|
||||
|
||||
do
|
||||
{
|
||||
ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
|
||||
if (ReadBytes > 0)
|
||||
_tprintf(_T("Received %d bytes from client\n"), ReadBytes);
|
||||
{
|
||||
_stprintf(temp, _T("Received %d bytes from client\n"), ReadBytes);
|
||||
LogEvent(temp, 0, FALSE);
|
||||
}
|
||||
else if (ReadBytes == SOCKET_ERROR)
|
||||
{
|
||||
_tprintf(("Socket Error: %d\n"), WSAGetLastError());
|
||||
_stprintf(temp, ("Socket Error: %d\n"), WSAGetLastError());
|
||||
LogEvent(temp, 0, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
} while (ReadBytes > 0);
|
||||
|
||||
_tprintf(("Connection closed by peer.\n"));
|
||||
LogEvent(_T("Discard: Connection closed by peer.\n"), 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -12,9 +12,6 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winsock2.h>
|
||||
#include <tchar.h>
|
||||
#include "tcpsvcs.h"
|
||||
|
||||
DWORD WINAPI EchoHandler(VOID* Sock_)
|
||||
|
@ -23,21 +20,21 @@ DWORD WINAPI EchoHandler(VOID* Sock_)
|
|||
SOCKET Sock = (SOCKET)Sock_;
|
||||
|
||||
if (!EchoIncomingPackets(Sock)) {
|
||||
_tprintf(_T("Echo incoming packets failed\n"));
|
||||
LogEvent(_T("Echo: EchoIncomingPackets failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Shutting connection down...\n"));
|
||||
if (ShutdownConnection(Sock, TRUE)) {
|
||||
_tprintf(_T("Connection is down.\n"));
|
||||
}
|
||||
LogEvent(_T("Echo: Shutting connection down...\n"), 0, FALSE);
|
||||
|
||||
if (ShutdownConnection(Sock, TRUE))
|
||||
LogEvent(_T("Echo: Connection is down\n"), 0, FALSE);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("Connection shutdown failed\n"));
|
||||
LogEvent(_T("Echo: Connection shutdown failed\n"), 0, FALSE);
|
||||
RetVal = -1;
|
||||
}
|
||||
|
||||
_tprintf(_T("Terminating echo thread\n"));
|
||||
LogEvent(_T("Echo: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(RetVal);
|
||||
}
|
||||
|
||||
|
@ -46,6 +43,7 @@ DWORD WINAPI EchoHandler(VOID* Sock_)
|
|||
BOOL EchoIncomingPackets(SOCKET Sock)
|
||||
{
|
||||
TCHAR ReadBuffer[BUF];
|
||||
TCHAR temp[512]; // temp for holding LogEvent text
|
||||
INT Temp;
|
||||
INT ReadBytes;
|
||||
INT SentBytes;
|
||||
|
@ -54,7 +52,8 @@ BOOL EchoIncomingPackets(SOCKET Sock)
|
|||
ReadBytes = recv(Sock, ReadBuffer, BUF, 0);
|
||||
if (ReadBytes > 0)
|
||||
{
|
||||
_tprintf(_T("Received %d bytes from client\n"), ReadBytes);
|
||||
_stprintf(temp, _T("Received %d bytes from client\n"), ReadBytes);
|
||||
LogEvent(temp, 0, FALSE);
|
||||
|
||||
SentBytes = 0;
|
||||
while (SentBytes < ReadBytes)
|
||||
|
@ -63,7 +62,8 @@ BOOL EchoIncomingPackets(SOCKET Sock)
|
|||
ReadBytes - SentBytes, 0);
|
||||
if (Temp > 0)
|
||||
{
|
||||
_tprintf(_T("Sent %d bytes back to client\n"), Temp);
|
||||
_stprintf(temp, _T("Sent %d bytes back to client\n"), Temp);
|
||||
LogEvent(temp, 0, FALSE);
|
||||
SentBytes += Temp;
|
||||
}
|
||||
else if (Temp == SOCKET_ERROR)
|
||||
|
@ -72,7 +72,8 @@ BOOL EchoIncomingPackets(SOCKET Sock)
|
|||
{
|
||||
/* Client closed connection before we could reply to
|
||||
all the data it sent, so quit early. */
|
||||
_tprintf(_T("Peer unexpectedly dropped connection!\n"));
|
||||
_stprintf(temp, _T("Peer unexpectedly dropped connection!\n"));
|
||||
LogEvent(temp, 0, FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +83,6 @@ BOOL EchoIncomingPackets(SOCKET Sock)
|
|||
|
||||
} while (ReadBytes != 0);
|
||||
|
||||
_tprintf(("Connection closed by peer.\n"));
|
||||
LogEvent(_T("Echo: Connection closed by peer.\n"), 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "tcpsvcs.h"
|
||||
|
||||
#define QBUFSIZ 160
|
||||
#define NUMQUOTES 60
|
||||
|
||||
LPCTSTR FilePath = _T("\\drivers\\etc\\quotes");
|
||||
|
||||
|
@ -28,51 +27,55 @@ DWORD WINAPI QotdHandler(VOID* Sock_)
|
|||
FILE *fp;
|
||||
SOCKET Sock;
|
||||
TCHAR Sys[MAX_PATH];
|
||||
TCHAR Quote[NUMQUOTES][BUFSIZ]; // need to set this dynamically
|
||||
TCHAR Quote[60][BUFSIZ]; // need to set this dynamically
|
||||
INT QuoteToPrint;
|
||||
INT i = 0;
|
||||
INT NumQuotes;
|
||||
|
||||
Sock = (SOCKET)Sock_;
|
||||
|
||||
if(! GetSystemDirectory(Sys, MAX_PATH))
|
||||
_tprintf(_T("Getting system path failed. Error: %lu\n"), GetLastError());
|
||||
{
|
||||
LogEvent(_T("QOTD: Getting system path failed.\n"), 0, TRUE);
|
||||
ExitThread(-1);
|
||||
}
|
||||
|
||||
_tcscat(Sys, FilePath);
|
||||
|
||||
_tprintf(_T("Opening quotes file\n"));
|
||||
LogEvent(_T("QOTD: Opening quotes file\n"), 0, FALSE);
|
||||
if ((fp = _tfopen(Sys, "r")) == NULL)
|
||||
{
|
||||
_tprintf(_T("Error opening file: %lu\n"), GetLastError());
|
||||
_tprintf(_T("Terminating qotd thread\n"));
|
||||
LogEvent(_T("QOTD: Error opening quote file\n"), 0, TRUE);
|
||||
LogEvent(_T("QOTD: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(-1);
|
||||
}
|
||||
|
||||
while (_fgetts(Quote[i], QBUFSIZ, fp) != NULL)
|
||||
i++;
|
||||
/* read all quotes in the file into an array */
|
||||
NumQuotes = 0;
|
||||
while (_fgetts(Quote[NumQuotes], QBUFSIZ, fp) != NULL)
|
||||
NumQuotes++;
|
||||
|
||||
_tprintf(_T("Closing quotes file\n"));
|
||||
LogEvent(_T("QOTD: Closing quotes file\n"), 0, FALSE);
|
||||
fclose(fp);
|
||||
|
||||
/* randomise the quote */
|
||||
srand((unsigned int) time(0));
|
||||
QuoteToPrint = rand() % NUMQUOTES;
|
||||
QuoteToPrint = rand() % NumQuotes;
|
||||
|
||||
if (!SendQuote(Sock, Quote[QuoteToPrint]))
|
||||
{
|
||||
_tprintf(_T("Error sending data. Error: %x\n"), WSAGetLastError());
|
||||
}
|
||||
LogEvent(_T("QOTD: Error sending data\n"), 0, TRUE);
|
||||
|
||||
_tprintf(_T("Shutting connection down...\n"));
|
||||
|
||||
LogEvent(_T("QOTD: Shutting connection down...\n"), 0, FALSE);
|
||||
if (ShutdownConnection(Sock, FALSE))
|
||||
_tprintf(_T("Connection is down.\n"));
|
||||
LogEvent(_T("QOTD: Connection is down\n"), 0, FALSE);
|
||||
else
|
||||
{
|
||||
_tprintf(_T("Connection shutdown failed\n"));
|
||||
_tprintf(_T("Terminating qotd thread\n"));
|
||||
LogEvent(_T("QOTD: Connection shutdown failed\n"), 0, FALSE);
|
||||
LogEvent(_T("QOTD: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(-1);
|
||||
}
|
||||
|
||||
_tprintf(_T("Terminating qotd thread\n"));
|
||||
LogEvent(_T("QOTD: Terminating thread\n"), 0, FALSE);
|
||||
ExitThread(0);
|
||||
|
||||
//return Retval;
|
||||
|
@ -90,6 +93,6 @@ BOOL SendQuote(SOCKET Sock, TCHAR* Quote)
|
|||
if (RetVal == SOCKET_ERROR)
|
||||
return FALSE;
|
||||
|
||||
_tprintf(("Connection closed by peer.\n"));
|
||||
LogEvent(_T("QOTD: Connection closed by peer\n"), 0, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -12,36 +12,35 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <winsock2.h>
|
||||
#include <tchar.h>
|
||||
#include "tcpsvcs.h"
|
||||
|
||||
extern BOOL bShutDownFlag;
|
||||
extern BOOL bPauseFlag;
|
||||
|
||||
DWORD WINAPI StartServer(LPVOID lpParam)
|
||||
{
|
||||
SOCKET ListeningSocket;
|
||||
PSERVICES pServices;
|
||||
const TCHAR* HostIP = "127.0.0.1";
|
||||
PSERVICES pServices;
|
||||
TCHAR temp[512];
|
||||
|
||||
pServices = (PSERVICES)lpParam;
|
||||
|
||||
//DebugBreak();
|
||||
ListeningSocket = SetUpListener(HostIP, htons(pServices->Port));
|
||||
if (ListeningSocket == INVALID_SOCKET)
|
||||
{
|
||||
_tprintf(_T("error setting up socket\n"));
|
||||
LogEvent("Socket error when setting up listener", 0, TRUE);
|
||||
return 3;
|
||||
}
|
||||
|
||||
_tprintf(_T("%s is waiting for connections on port %d...\n"),
|
||||
_stprintf(temp, _T("%s is waiting for connections on port %d...\n"),
|
||||
pServices->Name, pServices->Port);
|
||||
while (1)
|
||||
{
|
||||
AcceptConnections(ListeningSocket, pServices->Service, pServices->Name);
|
||||
printf("Acceptor restarting...\n");
|
||||
}
|
||||
LogEvent(temp, 0, FALSE);
|
||||
|
||||
/* won't see this yet as we kill the service with ctrl+c */
|
||||
_tprintf(_T("Detaching Winsock2...\n"));
|
||||
AcceptConnections(ListeningSocket, pServices->Service, pServices->Name);
|
||||
|
||||
LogEvent(_T("Detaching Winsock2...\n"), 0, FALSE);
|
||||
WSACleanup();
|
||||
return 0;
|
||||
}
|
||||
|
@ -64,49 +63,98 @@ SOCKET SetUpListener(const char* ServAddr, int Port)
|
|||
return Sock;
|
||||
}
|
||||
else
|
||||
printf("bind() failed\n");
|
||||
LogEvent(_T("bind() failed\n"), 0, TRUE);
|
||||
|
||||
}
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
/* note: consider allowing a maximum number of connections
|
||||
* A number of threads can be allocated and worker threads will
|
||||
* only be spawned if a free space is available
|
||||
|
||||
typedef struct _WORKER_THREAD {
|
||||
DWORD num;
|
||||
BOOL available;
|
||||
HANDLE hThread;
|
||||
} WORKER_THREAD;
|
||||
|
||||
*/
|
||||
|
||||
VOID AcceptConnections(SOCKET ListeningSocket,
|
||||
LPTHREAD_START_ROUTINE Service, TCHAR *Name)
|
||||
{
|
||||
SOCKADDR_IN Client;
|
||||
SOCKET Sock;
|
||||
HANDLE hThread;
|
||||
TIMEVAL TimeVal;
|
||||
FD_SET ReadFDS;
|
||||
INT nAddrSize = sizeof(Client);
|
||||
DWORD ThreadID;
|
||||
TCHAR temp[512];
|
||||
INT TimeOut = 2000; // 2 seconds
|
||||
|
||||
while (1)
|
||||
//DebugBreak();
|
||||
/* monitor for incomming connections */
|
||||
FD_ZERO(&ReadFDS);
|
||||
|
||||
/* set timeout values */
|
||||
TimeVal.tv_sec = TimeOut / 1000;
|
||||
TimeVal.tv_usec = TimeOut % 1000;
|
||||
|
||||
while (! bShutDownFlag) // (i<MAX_CLIENTS && !bShutDownFlag)
|
||||
{
|
||||
Sock = accept(ListeningSocket, (SOCKADDR*)&Client, &nAddrSize);
|
||||
if (Sock != INVALID_SOCKET)
|
||||
FD_SET(ListeningSocket, &ReadFDS);
|
||||
if (select(0, &ReadFDS, NULL, NULL, &TimeVal) == SOCKET_ERROR)
|
||||
{
|
||||
_tprintf(_T("Accepted connection to %s server from %s:%d\n"),
|
||||
Name, inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
|
||||
_tprintf(_T("Creating new thread for %s\n"), Name);
|
||||
CreateThread(0, 0, Service, (void*)Sock, 0, &ThreadID);
|
||||
}
|
||||
else
|
||||
{
|
||||
_tprintf(_T("accept() failed\n"));
|
||||
LogEvent(_T("select failed\n"), 0, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FD_ISSET(ListeningSocket, &ReadFDS))
|
||||
{
|
||||
Sock = accept(ListeningSocket, (SOCKADDR*)&Client, &nAddrSize);
|
||||
if (Sock != INVALID_SOCKET)
|
||||
{
|
||||
_stprintf(temp, _T("Accepted connection to %s server from %s:%d\n"),
|
||||
Name, inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
|
||||
LogEvent(temp, 0, FALSE);
|
||||
_stprintf(temp, _T("Creating new thread for %s\n"), Name);
|
||||
LogEvent(temp, 0, FALSE);
|
||||
|
||||
hThread = CreateThread(0, 0, Service, (void*)Sock, 0, &ThreadID);
|
||||
|
||||
/* Check the return value for success. */
|
||||
if (hThread == NULL)
|
||||
{
|
||||
_stprintf(temp, _T("Failed to start worker thread for "
|
||||
"the %s server....\n"), Name);
|
||||
LogEvent(temp, 0, TRUE);
|
||||
}
|
||||
|
||||
//Do we need to wait, or just kill it?
|
||||
WaitForSingleObject(hThread, INFINITE);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
LogEvent(_T("accept failed\n"), 0, TRUE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL ShutdownConnection(SOCKET Sock, BOOL bRec)
|
||||
{
|
||||
TCHAR temp[512];
|
||||
|
||||
/* Disallow any further data sends. This will tell the other side
|
||||
that we want to go away now. If we skip this step, we don't
|
||||
shut the connection down nicely. */
|
||||
if (shutdown(Sock, SD_SEND) == SOCKET_ERROR)
|
||||
{
|
||||
_tprintf(_T("Error in shutdown"));
|
||||
LogEvent(_T("Error in shutdown()\n"), 0, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -122,7 +170,10 @@ BOOL ShutdownConnection(SOCKET Sock, BOOL bRec)
|
|||
if (NewBytes == SOCKET_ERROR)
|
||||
return FALSE;
|
||||
else if (NewBytes != 0)
|
||||
_tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes);
|
||||
{
|
||||
_stprintf(temp, _T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes);
|
||||
LogEvent(temp, 0, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Close the socket. */
|
||||
|
|
|
@ -15,32 +15,31 @@
|
|||
* TODO:
|
||||
* - Start tcpsvcs as a service.
|
||||
* - write debugging function and print all dbg info via that.
|
||||
*
|
||||
* - change 'temp' to something meaningfull
|
||||
*/
|
||||
|
||||
#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";
|
||||
|
||||
static SERVICE_TABLE_ENTRY
|
||||
ServiceTable[2] =
|
||||
{
|
||||
{_T("tcpsvcs"), ServiceMain},
|
||||
{NULL, NULL}
|
||||
};
|
||||
#endif
|
||||
FILE *hLogFile;
|
||||
BOOL bShutDownFlag = FALSE;
|
||||
BOOL bPauseFlag = FALSE;
|
||||
|
||||
LPCTSTR LogFileName = "\\tcpsvcs_log.log";
|
||||
LPTSTR ServiceName = _T("Simp Tcp");
|
||||
//LPTSTR DisplayName = _T("Simple TCP/IP Services");
|
||||
|
||||
static SERVICES
|
||||
Services[NUM_SERVICES] =
|
||||
|
@ -53,79 +52,46 @@ Services[NUM_SERVICES] =
|
|||
};
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
_tprintf(_T("WSAStartup() failed : %lu\n"), RetVal);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create MAX_THREADS worker threads. */
|
||||
for( i=0; i<NUM_SERVICES; 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
|
||||
&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);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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[])
|
||||
{
|
||||
//DPRINT("tcpsvcs: main() started. See tcpsvcs_log.txt for info\n");
|
||||
SERVICE_TABLE_ENTRY ServiceTable[] =
|
||||
{
|
||||
{ServiceName, ServiceMain},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
if (!StartServiceCtrlDispatcher(ServiceTable))
|
||||
_tprintf(_T("failed to start the service control dispatcher\n"));
|
||||
//DPRINT("Starting tcpsvcs service. See \system32%s for logs\n", LogFileName);
|
||||
|
||||
//DPRINT("tcpsvcs: main() done\n");
|
||||
if (! StartServiceCtrlDispatcher(ServiceTable))
|
||||
LogEvent(_T("failed to start the service control dispatcher\n"), -1, TRUE);
|
||||
|
||||
//DPRINT("Shutdown tcpsvcs service\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static VOID WINAPI
|
||||
VOID WINAPI
|
||||
ServiceMain(DWORD argc, LPTSTR argv[])
|
||||
{
|
||||
DWORD i;
|
||||
TCHAR LogFilePath[MAX_PATH];
|
||||
|
||||
hLogFile = fopen(LogFileName, _T("w+"));
|
||||
if (hLogFile == NULL)
|
||||
if(! GetSystemDirectory(LogFilePath, MAX_PATH))
|
||||
return;
|
||||
|
||||
_tcscat(LogFilePath, LogFileName);
|
||||
|
||||
hLogFile = fopen(LogFilePath, _T("w"));
|
||||
if (hLogFile == NULL)
|
||||
{
|
||||
TCHAR *temp = NULL;
|
||||
|
||||
_stprintf(temp, _T("Could not open log file: %s"), LogFilePath);
|
||||
MessageBox(NULL, temp, NULL, MB_OK);
|
||||
return;
|
||||
}
|
||||
|
||||
LogEvent(_T("Entering ServiceMain"), 0, FALSE);
|
||||
|
||||
hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
|
||||
|
@ -133,13 +99,13 @@ ServiceMain(DWORD argc, LPTSTR argv[])
|
|||
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);
|
||||
SetServiceStatus (hSStat, &hServStatus);
|
||||
|
@ -158,6 +124,7 @@ ServiceMain(DWORD argc, LPTSTR argv[])
|
|||
completes, indicating system shutdown. */
|
||||
UpdateStatus (SERVICE_STOPPED, 0);
|
||||
LogEvent(_T("Service status set to SERVICE_STOPPED"), 0, FALSE);
|
||||
LogEvent(_T("Leaving ServiceMain"), 0, FALSE);
|
||||
fclose(hLogFile); /* Clean up everything, in general */
|
||||
return;
|
||||
|
||||
|
@ -170,14 +137,14 @@ ServerCtrlHandler(DWORD Control)
|
|||
{
|
||||
case SERVICE_CONTROL_SHUTDOWN: /* fall through */
|
||||
case SERVICE_CONTROL_STOP:
|
||||
ShutDown = TRUE;
|
||||
bShutDownFlag = TRUE;
|
||||
UpdateStatus(SERVICE_STOP_PENDING, -1);
|
||||
break;
|
||||
case SERVICE_CONTROL_PAUSE:
|
||||
PauseFlag = TRUE;
|
||||
bPauseFlag = TRUE;
|
||||
break;
|
||||
case SERVICE_CONTROL_CONTINUE:
|
||||
PauseFlag = FALSE;
|
||||
bPauseFlag = FALSE;
|
||||
break;
|
||||
case SERVICE_CONTROL_INTERROGATE:
|
||||
break;
|
||||
|
@ -193,11 +160,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"), -1, TRUE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -206,14 +179,27 @@ CreateServers()
|
|||
{
|
||||
DWORD dwThreadId[NUM_SERVICES];
|
||||
HANDLE hThread[NUM_SERVICES];
|
||||
WSADATA wsaData;
|
||||
TCHAR temp[512]; // temp for holding LogEvent text
|
||||
INT i;
|
||||
DWORD RetVal;
|
||||
|
||||
if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
|
||||
{
|
||||
_stprintf(temp, _T("WSAStartup() failed : %lu\n"), RetVal);
|
||||
LogEvent(temp, 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(temp, _T("Starting %s server....\n"), Services[i].Name);
|
||||
LogEvent(temp, 0, FALSE);
|
||||
|
||||
hThread[i] = CreateThread(
|
||||
NULL, // default security attributes
|
||||
|
@ -226,11 +212,18 @@ CreateServers()
|
|||
/* Check the return value for success. */
|
||||
if (hThread[i] == NULL)
|
||||
{
|
||||
_tprintf(_T("Failed to start %s server....\n"), Services[i].Name);
|
||||
_stprintf(temp, _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(temp, 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);
|
||||
|
||||
|
@ -254,26 +247,27 @@ LogEvent (LPCTSTR UserMessage, DWORD ExitCode, BOOL PrintErrorMsg)
|
|||
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("\n%s %s ErrNum = %lu. ExitCode = %lu."),
|
||||
UserMessage, lpvSysMsg, ErrNum, ExitCode);
|
||||
HeapFree (GetProcessHeap (), 0, lpvSysMsg);
|
||||
} else {
|
||||
_stprintf (MessageBuffer, _T("\n%s ExitCode = %d."),
|
||||
HeapFree(GetProcessHeap (), 0, lpvSysMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
_stprintf(MessageBuffer, _T("\n%s ExitCode = %lu."),
|
||||
UserMessage, ExitCode);
|
||||
}
|
||||
|
||||
fputs (MessageBuffer, hLogFile);
|
||||
|
||||
if (ExitCode > 0)
|
||||
ExitProcess (ExitCode);
|
||||
if (ExitCode != 0)
|
||||
ExitProcess(ExitCode);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,14 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <stdio.h>
|
||||
#include <winsock2.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#define UNICODE
|
||||
#define _UNICODE
|
||||
|
||||
/* default port numbers */
|
||||
#define ECHO_PORT 7
|
||||
#define DISCARD_PORT 9
|
||||
|
@ -41,7 +49,6 @@ typedef struct _Services {
|
|||
LPTHREAD_START_ROUTINE Service;
|
||||
} SERVICES, *PSERVICES;
|
||||
|
||||
|
||||
/* tcpsvcs functions */
|
||||
//static VOID WINAPI ServiceMain(DWORD argc, LPTSTR argv[]);
|
||||
VOID WINAPI ServerCtrlHandler(DWORD control);
|
||||
|
|
Loading…
Reference in a new issue