- Fix file logging to be asynchronous and more robust

- Convert to unicode

svn path=/trunk/; revision=35854
This commit is contained in:
Ged Murphy 2008-09-01 12:51:49 +00:00
parent e504422cb3
commit 5a12bfa450
9 changed files with 262 additions and 196 deletions

View file

@ -32,16 +32,16 @@ SendLine(SOCKET sock, LPSTR lpLine)
} }
else else
{ {
LogEvent(_T("Chargen: Not sent enough bytes"), 0, 0, LOG_FILE); LogEvent(L"Chargen: Not sent enough bytes", 0, 0, LOG_FILE);
} }
} }
else if (retVal == SOCKET_ERROR) else if (retVal == SOCKET_ERROR)
{ {
LogEvent(_T("Chargen: Socket error\n"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"Chargen: Socket error\n", WSAGetLastError(), 0, LOG_ERROR);
} }
else else
{ {
LogEvent(_T("Chargen: unknown error\n"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"Chargen: unknown error\n", WSAGetLastError(), 0, LOG_ERROR);
} }
return bRet;; return bRet;;
@ -100,21 +100,21 @@ ChargenHandler(VOID* sock_)
if (!GenerateChars(sock)) if (!GenerateChars(sock))
{ {
LogEvent(_T("Chargen: Char generation failed"), 0, 0, LOG_FILE); LogEvent(L"Chargen: Char generation failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("Chargen: Shutting connection down..."), 0, 0, LOG_FILE); LogEvent(L"Chargen: Shutting connection down...", 0, 0, LOG_FILE);
if (ShutdownConnection(sock, FALSE)) if (ShutdownConnection(sock, FALSE))
{ {
LogEvent(_T("Chargen: Connection is down"), 0, 0, LOG_FILE); LogEvent(L"Chargen: Connection is down", 0, 0, LOG_FILE);
} }
else else
{ {
LogEvent(_T("Chargen: Connection shutdown failed"), 0, 0, LOG_FILE); LogEvent(L"Chargen: Connection shutdown failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("Chargen: Terminating thread"), 0, 0, LOG_FILE); LogEvent(L"Chargen: Terminating thread", 0, 0, LOG_FILE);
ExitThread(retVal); ExitThread(retVal);
} }

View file

@ -15,7 +15,7 @@ SendTime(SOCKET sock, CHAR *time)
DWORD stringSize = strlen(time) + 1; DWORD stringSize = strlen(time) + 1;
if (send(sock, time, stringSize, 0) == SOCKET_ERROR) if (send(sock, time, stringSize, 0) == SOCKET_ERROR)
{ {
LogEvent(_T("DayTime: Error sending data"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"DayTime: Error sending data", WSAGetLastError(), 0, LOG_ERROR);
return FALSE; return FALSE;
} }
@ -41,15 +41,15 @@ DaytimeHandler(VOID* Sock_)
retVal = 1; retVal = 1;
} }
LogEvent(_T("DayTime: Shutting connection down"), 0, 0, LOG_FILE); LogEvent(L"DayTime: Shutting connection down", 0, 0, LOG_FILE);
if (ShutdownConnection(Sock, FALSE)) if (ShutdownConnection(Sock, FALSE))
LogEvent(_T("DayTime: Connection is down"), 0, 0, LOG_FILE); LogEvent(L"DayTime: Connection is down", 0, 0, LOG_FILE);
else else
{ {
LogEvent(_T("DayTime: Connection shutdown failed"), 0, 0, LOG_FILE); LogEvent(L"DayTime: Connection shutdown failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("DayTime: Terminating thread"), 0, 0, LOG_FILE); LogEvent(L"DayTime: Terminating thread", 0, 0, LOG_FILE);
ExitThread(retVal); ExitThread(retVal);
} }

View file

@ -14,7 +14,7 @@
static BOOL static BOOL
RecieveIncomingPackets(SOCKET sock) RecieveIncomingPackets(SOCKET sock)
{ {
char readBuffer[BUFSIZE]; CHAR readBuffer[BUFSIZE];
INT readBytes; INT readBytes;
do do
@ -24,18 +24,18 @@ RecieveIncomingPackets(SOCKET sock)
{ {
TCHAR logBuf[256]; TCHAR logBuf[256];
_stprintf(logBuf, _T("Discard: Received %d bytes from client"), readBytes); _swprintf(logBuf, L"Discard: Received %d bytes from client", readBytes);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
} }
else if (readBytes == SOCKET_ERROR) else if (readBytes == SOCKET_ERROR)
{ {
LogEvent(_T("Discard: Socket Error"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"Discard: Socket Error", WSAGetLastError(), 0, LOG_ERROR);
return FALSE; return FALSE;
} }
} while ((readBytes > 0) && (!bShutdown)); } while ((readBytes > 0) && (!bShutdown));
if (!bShutdown) if (!bShutdown)
LogEvent(_T("Discard: Connection closed by peer"), 0, 0, LOG_FILE); LogEvent(L"Discard: Connection closed by peer", 0, 0, LOG_FILE);
return TRUE; return TRUE;
} }
@ -48,21 +48,21 @@ DiscardHandler(VOID* sock_)
if (!RecieveIncomingPackets(sock)) if (!RecieveIncomingPackets(sock))
{ {
LogEvent(_T("Discard: RecieveIncomingPackets failed"), 0, 0, LOG_FILE); LogEvent(L"Discard: RecieveIncomingPackets failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("Discard: Shutting connection down"), 0, 0, LOG_FILE); LogEvent(L"Discard: Shutting connection down", 0, 0, LOG_FILE);
if (ShutdownConnection(sock, TRUE)) if (ShutdownConnection(sock, TRUE))
{ {
LogEvent(_T("Discard: Connection is down."), 0, 0, LOG_FILE); LogEvent(L"Discard: Connection is down.", 0, 0, LOG_FILE);
} }
else else
{ {
LogEvent(_T("Discard: Connection shutdown failed"), 0, 0, LOG_FILE); LogEvent(L"Discard: Connection shutdown failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("Discard: Terminating thread"), 0, 0, LOG_FILE); LogEvent(L"Discard: Terminating thread", 0, 0, LOG_FILE);
ExitThread(retVal); ExitThread(retVal);
} }

View file

@ -15,7 +15,7 @@ static BOOL
EchoIncomingPackets(SOCKET sock) EchoIncomingPackets(SOCKET sock)
{ {
CHAR readBuffer[RECV_BUF]; CHAR readBuffer[RECV_BUF];
TCHAR logBuf[256]; WCHAR logBuf[256];
INT totalSentBytes; INT totalSentBytes;
INT readBytes; INT readBytes;
INT retVal; INT retVal;
@ -25,7 +25,7 @@ EchoIncomingPackets(SOCKET sock)
readBytes = recv(sock, readBuffer, RECV_BUF, 0); readBytes = recv(sock, readBuffer, RECV_BUF, 0);
if (readBytes > 0) if (readBytes > 0)
{ {
_stprintf(logBuf, _T("Received %d bytes from client"), readBytes); _swprintf(logBuf, L"Received %d bytes from client", readBytes);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
totalSentBytes = 0; totalSentBytes = 0;
@ -34,33 +34,33 @@ EchoIncomingPackets(SOCKET sock)
retVal = send(sock, readBuffer + totalSentBytes, readBytes - totalSentBytes, 0); retVal = send(sock, readBuffer + totalSentBytes, readBytes - totalSentBytes, 0);
if (retVal > 0) if (retVal > 0)
{ {
_stprintf(logBuf, _T("Sent %d bytes back to client"), retVal); _swprintf(logBuf, L"Sent %d bytes back to client", retVal);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
totalSentBytes += retVal; totalSentBytes += retVal;
} }
else if (retVal == SOCKET_ERROR) else if (retVal == SOCKET_ERROR)
{ {
LogEvent(_T("Echo: socket error"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"Echo: socket error", WSAGetLastError(), 0, LOG_ERROR);
return FALSE; return FALSE;
} }
else else
{ {
/* Client closed connection before we could reply to /* Client closed connection before we could reply to
all the data it sent, so quit early. */ all the data it sent, so quit early. */
LogEvent(_T("Peer unexpectedly dropped connection!"), 0, 0, LOG_FILE); LogEvent(L"Peer unexpectedly dropped connection!", 0, 0, LOG_FILE);
return FALSE; return FALSE;
} }
} }
} }
else if (readBytes == SOCKET_ERROR) else if (readBytes == SOCKET_ERROR)
{ {
LogEvent(_T("Echo: socket error"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"Echo: socket error", WSAGetLastError(), 0, LOG_ERROR);
return FALSE; return FALSE;
} }
} while ((readBytes != 0) && (!bShutdown)); } while ((readBytes != 0) && (!bShutdown));
if (!bShutdown) if (!bShutdown)
LogEvent(_T("Echo: Connection closed by peer"), 0, 0, LOG_FILE); LogEvent(L"Echo: Connection closed by peer", 0, 0, LOG_FILE);
return TRUE; return TRUE;
} }
@ -73,22 +73,22 @@ EchoHandler(VOID* sock_)
if (!EchoIncomingPackets(sock)) if (!EchoIncomingPackets(sock))
{ {
LogEvent(_T("Echo: EchoIncomingPackets failed"), 0, 0, LOG_FILE); LogEvent(L"Echo: EchoIncomingPackets failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("Echo: Shutting connection down"), 0, 0, LOG_FILE); LogEvent(L"Echo: Shutting connection down", 0, 0, LOG_FILE);
if (ShutdownConnection(sock, TRUE)) if (ShutdownConnection(sock, TRUE))
{ {
LogEvent(_T("Echo: Connection is down"), 0, 0, LOG_FILE); LogEvent(L"Echo: Connection is down", 0, 0, LOG_FILE);
} }
else else
{ {
LogEvent(_T("Echo: Connection shutdown failed"), 0, 0, LOG_FILE); LogEvent(L"Echo: Connection shutdown failed", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("Echo: Terminating thread"), 0, 0, LOG_FILE); LogEvent(L"Echo: Terminating thread", 0, 0, LOG_FILE);
ExitThread(retVal); ExitThread(retVal);
} }

View file

@ -11,23 +11,27 @@
#define DEBUG #define DEBUG
static LPTSTR lpEventSource = _T("tcpsvcs"); static LPWSTR lpEventSource = L"tcpsvcs";
static LPCTSTR lpLogFileName = _T("C:\\tcpsvcs_log.log"); static LPCWSTR lpLogFileName = L"C:\\tcpsvcs_log.log";
static HANDLE hLogFile; static HANDLE hLogFile = NULL;
static BOOL bWaitingOnRead = FALSE;
static OVERLAPPED olWrite;
// needs work // needs work
static VOID static VOID
LogToEventLog(LPCTSTR lpMsg, LogToEventLog(LPCWSTR lpMsg,
DWORD errNum, DWORD errNum,
DWORD exitCode, DWORD exitCode,
UINT flags) UINT flags)
{ {
HANDLE hEventLog; HANDLE hEventLog;
hEventLog = RegisterEventSource(NULL, lpEventSource); hEventLog = RegisterEventSourceW(NULL, lpEventSource);
if (hEventLog) if (hEventLog)
{ {
ReportEvent(hEventLog, ReportEventW(hEventLog,
(flags & LOG_ERROR) ? EVENTLOG_ERROR_TYPE : EVENTLOG_SUCCESS, (flags & LOG_ERROR) ? EVENTLOG_ERROR_TYPE : EVENTLOG_SUCCESS,
0, 0,
0, 0,
@ -44,39 +48,39 @@ LogToEventLog(LPCTSTR lpMsg,
static BOOL static BOOL
OpenLogFile() OpenLogFile()
{ {
hLogFile = CreateFile(lpLogFileName, hLogFile = CreateFileW(lpLogFileName,
GENERIC_WRITE, GENERIC_WRITE,
0, 0,
NULL, NULL,
OPEN_ALWAYS, OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL); NULL);
if (hLogFile == INVALID_HANDLE_VALUE) if (hLogFile == INVALID_HANDLE_VALUE)
{
hLogFile = NULL;
return FALSE; return FALSE;
}
return TRUE; return TRUE;
} }
static VOID static VOID
LogToFile(LPCTSTR lpMsg, LogToFile(LPCWSTR lpMsg,
DWORD errNum, DWORD errNum,
DWORD exitCode, DWORD exitCode,
UINT flags) UINT flags)
{ {
LPTSTR lpFullMsg = NULL; LPWSTR lpFullMsg = NULL;
DWORD msgLen; DWORD msgLen;
if (!OpenLogFile()) msgLen = wcslen(lpMsg) + 1;
return;
msgLen = _tcslen(lpMsg) + 1;
if (flags & LOG_ERROR) if (flags & LOG_ERROR)
{ {
LPVOID lpSysMsg; LPVOID lpSysMsg;
DWORD eMsgLen; DWORD eMsgLen;
eMsgLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, eMsgLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, NULL,
errNum, errNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
@ -91,9 +95,9 @@ LogToFile(LPCTSTR lpMsg,
msgLen * sizeof(TCHAR)); msgLen * sizeof(TCHAR));
if (lpFullMsg) if (lpFullMsg)
{ {
_sntprintf(lpFullMsg, _snwprintf(lpFullMsg,
msgLen, msgLen,
_T("%s : %s\tErrNum = %lu ExitCode = %lu\r\n"), L"%s : %s\tErrNum = %lu ExitCode = %lu\r\n",
lpMsg, lpMsg,
lpSysMsg, lpSysMsg,
errNum, errNum,
@ -112,9 +116,9 @@ LogToFile(LPCTSTR lpMsg,
msgLen * sizeof(TCHAR)); msgLen * sizeof(TCHAR));
if (lpFullMsg) if (lpFullMsg)
{ {
_sntprintf(lpFullMsg, _snwprintf(lpFullMsg,
msgLen, msgLen,
_T("%s\r\n"), L"%s\r\n",
lpMsg); lpMsg);
} }
} }
@ -122,17 +126,50 @@ LogToFile(LPCTSTR lpMsg,
if (lpFullMsg) if (lpFullMsg)
{ {
DWORD bytesWritten; DWORD bytesWritten;
DWORD dwRet;
BOOL bRet;
SetFilePointer(hLogFile, 0, NULL, FILE_END); bRet = WriteFile(hLogFile,
WriteFile(hLogFile,
lpFullMsg, lpFullMsg,
_tcslen(lpFullMsg) * sizeof(TCHAR), wcslen(lpFullMsg) * sizeof(WCHAR),
&bytesWritten, &bytesWritten,
NULL); &olWrite);
if (bytesWritten == 0) if (!bRet)
{ {
LogToEventLog(_T("Failed to write to log file"), if (GetLastError() != ERROR_IO_PENDING)
{
bRet = FALSE;
}
else
{
// Write is pending
dwRet = WaitForSingleObject(olWrite.hEvent, INFINITE);
switch (dwRet)
{
// event has been signaled
case WAIT_OBJECT_0:
{
bRet = GetOverlappedResult(hLogFile,
&olWrite,
&bytesWritten,
FALSE);
break;
}
default:
// An error has occurred in WaitForSingleObject.
// This usually indicates a problem with the
// OVERLAPPED structure's event handle.
bRet = FALSE;
break;
}
}
}
if (!bRet || bytesWritten == 0)
{
LogToEventLog(L"Failed to write to log file",
GetLastError(), GetLastError(),
0, 0,
LOG_EVENTLOG | LOG_ERROR); LOG_EVENTLOG | LOG_ERROR);
@ -143,8 +180,6 @@ LogToFile(LPCTSTR lpMsg,
lpFullMsg); lpFullMsg);
} }
CloseHandle(hLogFile);
if (exitCode > 0) if (exitCode > 0)
ExitProcess(exitCode); ExitProcess(exitCode);
} }
@ -152,7 +187,7 @@ LogToFile(LPCTSTR lpMsg,
VOID VOID
LogEvent(LPCTSTR lpMsg, LogEvent(LPCWSTR lpMsg,
DWORD errNum, DWORD errNum,
DWORD exitCode, DWORD exitCode,
UINT flags) UINT flags)
@ -165,39 +200,64 @@ LogEvent(LPCTSTR lpMsg,
LogToEventLog(lpMsg, errNum, exitCode, flags); LogToEventLog(lpMsg, errNum, exitCode, flags);
} }
VOID BOOL
InitLogging() InitLogging()
{ {
WCHAR wcBom = 0xFEFF; #ifdef DEBUG
BOOL bRet = FALSE;
DeleteFile(lpLogFileName); ZeroMemory(&olWrite, sizeof(OVERLAPPED));
olWrite.Offset = 0xFFFFFFFF;
olWrite.OffsetHigh = 0xFFFFFFFF;
olWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (olWrite.hEvent)
{
DeleteFileW(lpLogFileName);
#ifdef _UNICODE
if (OpenLogFile()) if (OpenLogFile())
{ {
WCHAR wcBom = 0xFEFF;
DWORD bytesWritten; DWORD bytesWritten;
WriteFile(hLogFile, bRet = WriteFile(hLogFile,
&wcBom, &wcBom,
sizeof(WCHAR), sizeof(WCHAR),
&bytesWritten, &bytesWritten,
NULL); &olWrite);
if (bytesWritten == 0) if (!bRet)
{ {
LogToEventLog(_T("Failed to write to log file"), if (GetLastError() != ERROR_IO_PENDING)
{
LogToEventLog(L"Failed to write to log file",
GetLastError(), GetLastError(),
0, 0,
LOG_EVENTLOG | LOG_ERROR); LOG_EVENTLOG | LOG_ERROR);
} }
else
CloseHandle(hLogFile); {
bRet = TRUE;
} }
}
}
}
return bRet;
#else
return TRUE;
#endif #endif
} }
VOID VOID
UninitLogging() UninitLogging()
{ {
if (hLogFile)
{
FlushFileBuffers(hLogFile); FlushFileBuffers(hLogFile);
CloseHandle(hLogFile); CloseHandle(hLogFile);
}
if (olWrite.hEvent)
{
CloseHandle(olWrite.hEvent);
}
} }

View file

@ -9,7 +9,7 @@
#include "tcpsvcs.h" #include "tcpsvcs.h"
static LPCTSTR lpFilePath = _T("\\drivers\\etc\\quotes"); static WCHAR szFilePath[] = L"\\drivers\\etc\\quotes";
static BOOL static BOOL
SendQuote(SOCKET sock, char* Quote) SendQuote(SOCKET sock, char* Quote)
@ -25,24 +25,24 @@ static BOOL
RetrieveQuote(SOCKET sock) RetrieveQuote(SOCKET sock)
{ {
HANDLE hFile; HANDLE hFile;
TCHAR lpFullPath[MAX_PATH + 20]; WCHAR szFullPath[MAX_PATH + 20];
DWORD dwBytesRead; DWORD dwBytesRead;
LPSTR lpQuotes; LPSTR lpQuotes;
LPSTR lpStr; LPSTR lpStr;
DWORD quoteNum; INT quoteNum;
DWORD NumQuotes = 0; INT NumQuotes = 0;
INT i; INT i;
if(!GetSystemDirectory(lpFullPath, MAX_PATH)) if(!GetSystemDirectoryW(szFullPath, MAX_PATH))
{ {
LogEvent(_T("QOTD: Getting system path failed"), GetLastError(), 0, LOG_FILE); LogEvent(L"QOTD: Getting system path failed", GetLastError(), 0, LOG_FILE);
return FALSE; return FALSE;
} }
_tcscat(lpFullPath, lpFilePath); wcscat(szFullPath, szFilePath);
LogEvent(_T("QOTD: Opening quotes file"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Opening quotes file", 0, 0, LOG_FILE);
hFile = CreateFile(lpFullPath, hFile = CreateFileW(szFullPath,
GENERIC_READ, GENERIC_READ,
0, 0,
NULL, NULL,
@ -51,7 +51,7 @@ RetrieveQuote(SOCKET sock)
NULL); NULL);
if (hFile == INVALID_HANDLE_VALUE) if (hFile == INVALID_HANDLE_VALUE)
{ {
LogEvent(_T("QOTD: Error opening quotes file"), GetLastError(), 0, LOG_FILE); LogEvent(L"QOTD: Error opening quotes file", GetLastError(), 0, LOG_FILE);
} }
else else
{ {
@ -105,7 +105,7 @@ RetrieveQuote(SOCKET sock)
/* send the quote */ /* send the quote */
if (!SendQuote(sock, lpStart)) if (!SendQuote(sock, lpStart))
LogEvent(_T("QOTD: Error sending data"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Error sending data", 0, 0, LOG_FILE);
break; break;
} }
else else
@ -133,22 +133,22 @@ QotdHandler(VOID* sock_)
if (!RetrieveQuote(sock)) if (!RetrieveQuote(sock))
{ {
LogEvent(_T("QOTD: Error retrieving quote"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Error retrieving quote", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("QOTD: Shutting connection down"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Shutting connection down", 0, 0, LOG_FILE);
if (ShutdownConnection(sock, FALSE)) if (ShutdownConnection(sock, FALSE))
{ {
LogEvent(_T("QOTD: Connection is down"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Connection is down", 0, 0, LOG_FILE);
} }
else else
{ {
LogEvent(_T("QOTD: Connection shutdown failed"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Connection shutdown failed", 0, 0, LOG_FILE);
LogEvent(_T("QOTD: Terminating thread"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Terminating thread", 0, 0, LOG_FILE);
retVal = 1; retVal = 1;
} }
LogEvent(_T("QOTD: Terminating thread"), 0, 0, LOG_FILE); LogEvent(L"QOTD: Terminating thread", 0, 0, LOG_FILE);
ExitThread(retVal); ExitThread(retVal);
} }

View file

@ -33,17 +33,17 @@ SetUpListener(USHORT Port)
} }
else else
{ {
LogEvent(_T("listen() failed"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"listen() failed", WSAGetLastError(), 0, LOG_ERROR);
} }
} }
else else
{ {
LogEvent(_T("bind() failed"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"bind() failed", WSAGetLastError(), 0, LOG_ERROR);
} }
} }
else else
{ {
LogEvent(_T("socket() failed"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"socket() failed", WSAGetLastError(), 0, LOG_ERROR);
} }
return bSetup ? sock : INVALID_SOCKET; return bSetup ? sock : INVALID_SOCKET;
@ -53,14 +53,14 @@ SetUpListener(USHORT Port)
static VOID static VOID
AcceptConnections(SOCKET listeningSocket, AcceptConnections(SOCKET listeningSocket,
LPTHREAD_START_ROUTINE lpService, LPTHREAD_START_ROUTINE lpService,
LPTSTR lpName) LPWSTR lpName)
{ {
SOCKADDR_IN client; SOCKADDR_IN client;
SOCKET sock; SOCKET sock;
HANDLE hThread; HANDLE hThread;
TIMEVAL timeVal; TIMEVAL timeVal;
FD_SET readFD; FD_SET readFD;
TCHAR logBuf[256]; WCHAR logBuf[256];
INT timeOut = 2000; INT timeOut = 2000;
timeVal.tv_sec = timeOut / 1000; timeVal.tv_sec = timeOut / 1000;
@ -83,14 +83,14 @@ AcceptConnections(SOCKET listeningSocket,
sock = accept(listeningSocket, (SOCKADDR*)&client, &addrSize); sock = accept(listeningSocket, (SOCKADDR*)&client, &addrSize);
if (sock != INVALID_SOCKET) if (sock != INVALID_SOCKET)
{ {
_stprintf(logBuf, _swprintf(logBuf,
_T("Accepted connection to %s server from %s:%d"), L"Accepted connection to %s server from %S:%d",
lpName, lpName,
inet_ntoa(client.sin_addr), inet_ntoa(client.sin_addr),
ntohs(client.sin_port)); ntohs(client.sin_port));
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
_stprintf(logBuf, _T("Creating worker thread for %s"), lpName); _swprintf(logBuf, L"Creating worker thread for %s", lpName);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
if (!bShutdown) if (!bShutdown)
@ -102,7 +102,7 @@ AcceptConnections(SOCKET listeningSocket,
} }
else else
{ {
_stprintf(logBuf, _T("Failed to start worker thread for the %s server"), _swprintf(logBuf, L"Failed to start worker thread for the %s server",
lpName); lpName);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
} }
@ -110,13 +110,13 @@ AcceptConnections(SOCKET listeningSocket,
} }
else else
{ {
LogEvent(_T("accept failed"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"accept failed", WSAGetLastError(), 0, LOG_ERROR);
} }
} }
} }
else if (selRet == SOCKET_ERROR) else if (selRet == SOCKET_ERROR)
{ {
LogEvent(_T("select failed"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"select failed", WSAGetLastError(), 0, LOG_ERROR);
} }
} }
} }
@ -125,14 +125,14 @@ BOOL
ShutdownConnection(SOCKET sock, ShutdownConnection(SOCKET sock,
BOOL bRec) BOOL bRec)
{ {
TCHAR logBuf[256]; WCHAR logBuf[256];
/* Disallow any further data sends. This will tell the other side /* 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 that we want to go away now. If we skip this step, we don't
shut the connection down nicely. */ shut the connection down nicely. */
if (shutdown(sock, SD_SEND) == SOCKET_ERROR) if (shutdown(sock, SD_SEND) == SOCKET_ERROR)
{ {
LogEvent(_T("Error in shutdown()"), WSAGetLastError(), 0, LOG_ERROR); LogEvent(L"Error in shutdown()", WSAGetLastError(), 0, LOG_ERROR);
return FALSE; return FALSE;
} }
@ -148,7 +148,7 @@ ShutdownConnection(SOCKET sock,
ret = recv(sock, readBuffer, BUF, 0); ret = recv(sock, readBuffer, BUF, 0);
if (ret >= 0) if (ret >= 0)
{ {
_stprintf(logBuf, _T("FYI, received %d unexpected bytes during shutdown"), ret); _swprintf(logBuf, L"FYI, received %d unexpected bytes during shutdown", ret);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
} }
} while (ret > 0); } while (ret > 0);
@ -169,7 +169,7 @@ StartServer(LPVOID lpParam)
pServices = (PSERVICES)lpParam; pServices = (PSERVICES)lpParam;
_stprintf(logBuf, _T("Starting %s server"), pServices->Name); _swprintf(logBuf, L"Starting %s server", pServices->lpName);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
if (!bShutdown) if (!bShutdown)
@ -177,23 +177,23 @@ StartServer(LPVOID lpParam)
listeningSocket = SetUpListener(htons(pServices->Port)); listeningSocket = SetUpListener(htons(pServices->Port));
if (!bShutdown && listeningSocket != INVALID_SOCKET) if (!bShutdown && listeningSocket != INVALID_SOCKET)
{ {
_stprintf(logBuf, _swprintf(logBuf,
_T("%s is waiting for connections on port %d"), L"%s is waiting for connections on port %d",
pServices->Name, pServices->lpName,
pServices->Port); pServices->Port);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
AcceptConnections(listeningSocket, pServices->Service, pServices->Name); AcceptConnections(listeningSocket, pServices->lpService, pServices->lpName);
} }
else else
{ {
LogEvent(_T("Socket error when setting up listener"), 0, 0, LOG_FILE); LogEvent(L"Socket error when setting up listener", 0, 0, LOG_FILE);
} }
} }
_stprintf(logBuf, _swprintf(logBuf,
_T("Exiting %s thread"), L"Exiting %s thread",
pServices->Name); pServices->lpName);
LogEvent(logBuf, 0, 0, LOG_FILE); LogEvent(logBuf, 0, 0, LOG_FILE);
ExitThread(0); ExitThread(0);
} }

View file

@ -9,7 +9,7 @@
#include "tcpsvcs.h" #include "tcpsvcs.h"
static LPTSTR ServiceName = _T("tcpsvcs"); static WCHAR ServiceName[] = L"tcpsvcs";
volatile BOOL bShutdown = FALSE; volatile BOOL bShutdown = FALSE;
volatile BOOL bPause = FALSE; volatile BOOL bPause = FALSE;
@ -23,11 +23,11 @@ typedef struct _ServiceInfo
static SERVICES static SERVICES
Services[NUM_SERVICES] = Services[NUM_SERVICES] =
{ {
{ECHO_PORT, _T("Echo"), EchoHandler}, {ECHO_PORT, L"Echo", EchoHandler},
{DISCARD_PORT, _T("Discard"), DiscardHandler}, {DISCARD_PORT, L"Discard", DiscardHandler},
{DAYTIME_PORT, _T("Daytime"), DaytimeHandler}, {DAYTIME_PORT, L"Daytime", DaytimeHandler},
{QOTD_PORT, _T("QOTD"), QotdHandler}, {QOTD_PORT, L"QOTD", QotdHandler},
{CHARGEN_PORT, _T("Chargen"), ChargenHandler} {CHARGEN_PORT, L"Chargen", ChargenHandler}
}; };
@ -36,7 +36,7 @@ UpdateStatus(PSERVICEINFO pServInfo,
DWORD NewStatus, DWORD NewStatus,
DWORD Check) DWORD Check)
{ {
TCHAR szSet[50]; WCHAR szSet[50];
if (Check > 0) if (Check > 0)
pServInfo->servStatus.dwCheckPoint += Check; pServInfo->servStatus.dwCheckPoint += Check;
@ -46,15 +46,15 @@ UpdateStatus(PSERVICEINFO pServInfo,
if (NewStatus > 0) if (NewStatus > 0)
pServInfo->servStatus.dwCurrentState = NewStatus; pServInfo->servStatus.dwCurrentState = NewStatus;
_sntprintf(szSet, _snwprintf(szSet,
49, 49,
_T("Service state 0x%lu, CheckPoint %lu"), L"Service state 0x%lu, CheckPoint %lu",
pServInfo->servStatus.dwCurrentState, pServInfo->servStatus.dwCurrentState,
pServInfo->servStatus.dwCheckPoint); pServInfo->servStatus.dwCheckPoint);
LogEvent(szSet, 0, 0, LOG_FILE); LogEvent(szSet, 0, 0, LOG_FILE);
if (!SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus)) if (!SetServiceStatus(pServInfo->hStatus, &pServInfo->servStatus))
LogEvent(_T("Cannot set service status"), GetLastError(), 0, LOG_ALL); LogEvent(L"Cannot set service status", GetLastError(), 0, LOG_ALL);
} }
@ -64,25 +64,25 @@ CreateServers(PSERVICEINFO pServInfo)
DWORD dwThreadId[NUM_SERVICES]; DWORD dwThreadId[NUM_SERVICES];
HANDLE hThread[NUM_SERVICES]; HANDLE hThread[NUM_SERVICES];
WSADATA wsaData; WSADATA wsaData;
TCHAR buf[256]; WCHAR buf[256];
INT i; INT i;
DWORD RetVal; DWORD RetVal;
if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
{ {
_stprintf(buf, _T("WSAStartup() failed : %lu\n"), RetVal); _swprintf(buf, L"WSAStartup() failed : %lu\n", RetVal);
LogEvent(buf, 0, 100, LOG_ALL); LogEvent(buf, 0, 100, LOG_ALL);
return FALSE; return FALSE;
} }
UpdateStatus(pServInfo, 0, 1); UpdateStatus(pServInfo, 0, 1);
LogEvent(_T("\nCreating server Threads"), 0, 0, LOG_FILE); LogEvent(L"\nCreating server Threads", 0, 0, LOG_FILE);
/* Create worker threads. */ /* Create worker threads. */
for(i = 0; i < NUM_SERVICES; i++) for (i = 0; i < NUM_SERVICES; i++)
{ {
_stprintf(buf, _T("Creating thread for %s server"), Services[i].Name); _swprintf(buf, L"Creating thread for %s server", Services[i].lpName);
LogEvent(buf, 0, 0, LOG_FILE); LogEvent(buf, 0, 0, LOG_FILE);
hThread[i] = CreateThread(NULL, hThread[i] = CreateThread(NULL,
@ -94,26 +94,26 @@ CreateServers(PSERVICEINFO pServInfo)
if (hThread[i] == NULL) if (hThread[i] == NULL)
{ {
_stprintf(buf, _T("\nFailed to start %s server\n"), Services[i].Name); _swprintf(buf, L"\nFailed to start %s server\n", Services[i].lpName);
LogEvent(buf, GetLastError(), 0, LOG_ALL); LogEvent(buf, GetLastError(), 0, LOG_ALL);
} }
UpdateStatus(pServInfo, 0, 1); UpdateStatus(pServInfo, 0, 1);
} }
LogEvent(_T("Setting service status to running"), 0, 0, LOG_FILE); LogEvent(L"Setting service status to running", 0, 0, LOG_FILE);
UpdateStatus(pServInfo, SERVICE_RUNNING, 0); UpdateStatus(pServInfo, SERVICE_RUNNING, 0);
/* Wait until all threads have terminated. */ /* Wait until all threads have terminated. */
WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE); WaitForMultipleObjects(NUM_SERVICES, hThread, TRUE, INFINITE);
for(i = 0; i < NUM_SERVICES; i++) for (i = 0; i < NUM_SERVICES; i++)
{ {
if (hThread[i] != NULL) if (hThread[i] != NULL)
CloseHandle(hThread[i]); CloseHandle(hThread[i]);
} }
LogEvent(_T("Detaching Winsock2"), 0, 0, LOG_FILE); LogEvent(L"Detaching Winsock2", 0, 0, LOG_FILE);
WSACleanup(); WSACleanup();
return 0; return 0;
@ -131,7 +131,7 @@ ServerCtrlHandler(DWORD dwControl,
{ {
case SERVICE_CONTROL_SHUTDOWN: case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP: case SERVICE_CONTROL_STOP:
LogEvent(_T("\nSetting the service to SERVICE_STOP_PENDING"), 0, 0, LOG_FILE); LogEvent(L"\nSetting the service to SERVICE_STOP_PENDING", 0, 0, LOG_FILE);
InterlockedExchange((LONG *)&bShutdown, TRUE); InterlockedExchange((LONG *)&bShutdown, TRUE);
pServInfo->servStatus.dwWin32ExitCode = 0; pServInfo->servStatus.dwWin32ExitCode = 0;
pServInfo->servStatus.dwWaitHint = 0; pServInfo->servStatus.dwWaitHint = 0;
@ -139,13 +139,13 @@ ServerCtrlHandler(DWORD dwControl,
break; break;
case SERVICE_CONTROL_PAUSE: /* not yet implemented */ case SERVICE_CONTROL_PAUSE: /* not yet implemented */
LogEvent(_T("Setting the service to SERVICE_PAUSED"), 0, 0, LOG_FILE); LogEvent(L"Setting the service to SERVICE_PAUSED", 0, 0, LOG_FILE);
InterlockedExchange((LONG *)&bPause, TRUE); InterlockedExchange((LONG *)&bPause, TRUE);
UpdateStatus(pServInfo, SERVICE_PAUSED, 0); UpdateStatus(pServInfo, SERVICE_PAUSED, 0);
break; break;
case SERVICE_CONTROL_CONTINUE: case SERVICE_CONTROL_CONTINUE:
LogEvent(_T("Setting the service to SERVICE_RUNNING"), 0, 0, LOG_FILE); LogEvent(L"Setting the service to SERVICE_RUNNING", 0, 0, LOG_FILE);
InterlockedExchange((LONG *)&bPause, FALSE); InterlockedExchange((LONG *)&bPause, FALSE);
UpdateStatus(pServInfo, SERVICE_RUNNING, 0); UpdateStatus(pServInfo, SERVICE_RUNNING, 0);
break; break;
@ -155,19 +155,19 @@ ServerCtrlHandler(DWORD dwControl,
default: default:
if (dwControl > 127 && dwControl < 256) /* user defined */ if (dwControl > 127 && dwControl < 256) /* user defined */
LogEvent(_T("User defined control code"), 0, 0, LOG_FILE); LogEvent(L"User defined control code", 0, 0, LOG_FILE);
else else
LogEvent(_T("ERROR: Bad control code"), 0, 0, LOG_FILE); LogEvent(L"ERROR: Bad control code", 0, 0, LOG_FILE);
break; break;
} }
} }
VOID WINAPI VOID WINAPI
ServiceMain(DWORD argc, LPTSTR argv[]) ServiceMain(DWORD argc, LPWSTR argv[])
{ {
SERVICEINFO servInfo; SERVICEINFO servInfo;
LogEvent (_T("Entering ServiceMain."), 0, 0, LOG_FILE); LogEvent(L"Entering ServiceMain.", 0, 0, LOG_FILE);
servInfo.servStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; servInfo.servStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
servInfo.servStatus.dwCurrentState = SERVICE_STOPPED; servInfo.servStatus.dwCurrentState = SERVICE_STOPPED;
@ -177,12 +177,12 @@ ServiceMain(DWORD argc, LPTSTR argv[])
servInfo.servStatus.dwCheckPoint = 0; servInfo.servStatus.dwCheckPoint = 0;
servInfo.servStatus.dwWaitHint = 2 * CS_TIMEOUT; servInfo.servStatus.dwWaitHint = 2 * CS_TIMEOUT;
LogEvent(_T("Registering service control handler"), 0, 0, LOG_FILE); LogEvent(L"Registering service control handler", 0, 0, LOG_FILE);
servInfo.hStatus = RegisterServiceCtrlHandlerEx(ServiceName, servInfo.hStatus = RegisterServiceCtrlHandlerExW(ServiceName,
(LPHANDLER_FUNCTION_EX)ServerCtrlHandler, (LPHANDLER_FUNCTION_EX)ServerCtrlHandler,
&servInfo); &servInfo);
if (!servInfo.hStatus) if (!servInfo.hStatus)
LogEvent(_T("Failed to register service\n"), GetLastError(), 100, LOG_ALL); LogEvent(L"Failed to register service", GetLastError(), 100, LOG_ALL);
UpdateStatus(&servInfo, SERVICE_START_PENDING, 1); UpdateStatus(&servInfo, SERVICE_START_PENDING, 1);
@ -193,27 +193,28 @@ ServiceMain(DWORD argc, LPTSTR argv[])
return; return;
} }
LogEvent(_T("Service threads shut down. Set SERVICE_STOPPED status"), 0, 0, LOG_FILE); LogEvent(L"Service threads shut down. Set SERVICE_STOPPED status", 0, 0, LOG_FILE);
UpdateStatus(&servInfo, SERVICE_STOPPED, 0); UpdateStatus(&servInfo, SERVICE_STOPPED, 0);
LogEvent(_T("Leaving ServiceMain\n"), 0, 0, LOG_FILE); LogEvent(L"Leaving ServiceMain\n", 0, 0, LOG_FILE);
} }
int _tmain (int argc, LPTSTR argv []) int _tmain (int argc, LPTSTR argv [])
{ {
SERVICE_TABLE_ENTRY ServiceTable[] = SERVICE_TABLE_ENTRYW ServiceTable[] =
{ {
{ServiceName, ServiceMain}, {ServiceName, ServiceMain},
{NULL, NULL } {NULL, NULL }
}; };
InitLogging(); if (InitLogging())
{
if (!StartServiceCtrlDispatcher(ServiceTable)) if (!StartServiceCtrlDispatcherW(ServiceTable))
LogEvent(_T("failed to start the service control dispatcher"), GetLastError(), 101, LOG_ALL); LogEvent(L"failed to start the service control dispatcher", GetLastError(), 101, LOG_ALL);
UninitLogging(); UninitLogging();
}
return 0; return 0;
} }

View file

@ -3,6 +3,10 @@
#include <tchar.h> #include <tchar.h>
#include <time.h> #include <time.h>
#ifndef _MSC_VER
#define _swprintf swprintf
#endif
#define LOG_FILE 1 #define LOG_FILE 1
#define LOG_EVENTLOG 2 #define LOG_EVENTLOG 2
#define LOG_ERROR 4 #define LOG_ERROR 4
@ -20,19 +24,20 @@
/* data structure to pass to threads */ /* data structure to pass to threads */
typedef struct _Services { typedef struct _Services
{
USHORT Port; USHORT Port;
TCHAR *Name; LPWSTR lpName;
LPTHREAD_START_ROUTINE Service; LPTHREAD_START_ROUTINE lpService;
} SERVICES, *PSERVICES; } SERVICES, *PSERVICES;
extern volatile BOOL bShutdown; extern volatile BOOL bShutdown;
extern volatile BOOL bPause; extern volatile BOOL bPause;
/* logging functions */ /* logging functions */
VOID InitLogging(); BOOL InitLogging();
VOID UninitLogging(); VOID UninitLogging();
VOID LogEvent(LPCTSTR lpMsg, DWORD errNum, DWORD exitCode, UINT flags); VOID LogEvent(LPCWSTR lpMsg, DWORD errNum, DWORD exitCode, UINT flags);
/* skelserver functions */ /* skelserver functions */
DWORD WINAPI StartServer(LPVOID lpParam); DWORD WINAPI StartServer(LPVOID lpParam);