2008-04-02 16:54:55 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS simple TCP/IP services
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2015-09-12 10:58:07 +00:00
|
|
|
* FILE: base/services/tcpsvcs/log.c
|
2008-04-02 16:54:55 +00:00
|
|
|
* PURPOSE: Logging functionality for the service
|
|
|
|
* COPYRIGHT: Copyright 2008 Ged Murphy <gedmurphy@reactos.org>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "tcpsvcs.h"
|
|
|
|
|
|
|
|
#define DEBUG
|
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
static LPWSTR lpEventSource = L"tcpsvcs";
|
2018-08-28 10:45:03 +00:00
|
|
|
static WCHAR szLogFileName[MAX_PATH];
|
2008-09-01 12:51:49 +00:00
|
|
|
static HANDLE hLogFile = NULL;
|
|
|
|
|
|
|
|
static OVERLAPPED olWrite;
|
|
|
|
|
2008-04-02 16:54:55 +00:00
|
|
|
|
|
|
|
// needs work
|
|
|
|
static VOID
|
2008-09-01 12:51:49 +00:00
|
|
|
LogToEventLog(LPCWSTR lpMsg,
|
2008-04-02 16:54:55 +00:00
|
|
|
DWORD errNum,
|
|
|
|
DWORD exitCode,
|
|
|
|
UINT flags)
|
|
|
|
{
|
|
|
|
HANDLE hEventLog;
|
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
hEventLog = RegisterEventSourceW(NULL, lpEventSource);
|
2008-04-02 16:54:55 +00:00
|
|
|
if (hEventLog)
|
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
ReportEventW(hEventLog,
|
|
|
|
(flags & LOG_ERROR) ? EVENTLOG_ERROR_TYPE : EVENTLOG_SUCCESS,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
1,
|
|
|
|
0,
|
|
|
|
&lpMsg,
|
|
|
|
NULL);
|
2008-04-02 16:54:55 +00:00
|
|
|
|
|
|
|
CloseEventLog(hEventLog);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
|
|
|
OpenLogFile()
|
|
|
|
{
|
2018-08-28 10:45:03 +00:00
|
|
|
hLogFile = CreateFileW(szLogFileName,
|
2008-09-01 12:51:49 +00:00
|
|
|
GENERIC_WRITE,
|
2008-09-02 08:05:25 +00:00
|
|
|
FILE_SHARE_READ,
|
2008-09-01 12:51:49 +00:00
|
|
|
NULL,
|
|
|
|
OPEN_ALWAYS,
|
|
|
|
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
|
|
|
|
NULL);
|
|
|
|
if (hLogFile == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
hLogFile = NULL;
|
2008-04-02 16:54:55 +00:00
|
|
|
return FALSE;
|
2008-09-01 12:51:49 +00:00
|
|
|
}
|
2008-04-02 16:54:55 +00:00
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VOID
|
2008-09-01 12:51:49 +00:00
|
|
|
LogToFile(LPCWSTR lpMsg,
|
2008-04-02 16:54:55 +00:00
|
|
|
DWORD errNum,
|
|
|
|
DWORD exitCode,
|
|
|
|
UINT flags)
|
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
LPWSTR lpFullMsg = NULL;
|
2018-07-07 14:09:03 +00:00
|
|
|
SIZE_T msgLen;
|
2008-04-02 16:54:55 +00:00
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
msgLen = wcslen(lpMsg) + 1;
|
2008-04-02 16:54:55 +00:00
|
|
|
|
|
|
|
if (flags & LOG_ERROR)
|
|
|
|
{
|
2018-07-07 14:09:03 +00:00
|
|
|
LPWSTR lpSysMsg;
|
2008-04-02 16:54:55 +00:00
|
|
|
DWORD eMsgLen;
|
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
eMsgLen = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
|
|
NULL,
|
|
|
|
errNum,
|
|
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
2018-07-07 14:09:03 +00:00
|
|
|
(LPWSTR)&lpSysMsg,
|
2008-09-01 12:51:49 +00:00
|
|
|
0,
|
|
|
|
NULL);
|
2008-04-02 16:54:55 +00:00
|
|
|
|
|
|
|
msgLen = msgLen + eMsgLen + 40;
|
|
|
|
|
|
|
|
lpFullMsg = HeapAlloc(GetProcessHeap(),
|
|
|
|
0,
|
|
|
|
msgLen * sizeof(TCHAR));
|
|
|
|
if (lpFullMsg)
|
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
_snwprintf(lpFullMsg,
|
2008-04-02 16:54:55 +00:00
|
|
|
msgLen,
|
2008-09-01 12:51:49 +00:00
|
|
|
L"%s : %s\tErrNum = %lu ExitCode = %lu\r\n",
|
2008-04-02 16:54:55 +00:00
|
|
|
lpMsg,
|
|
|
|
lpSysMsg,
|
|
|
|
errNum,
|
|
|
|
exitCode);
|
|
|
|
}
|
|
|
|
|
|
|
|
LocalFree(lpSysMsg);
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
msgLen += 2;
|
|
|
|
|
|
|
|
lpFullMsg = HeapAlloc(GetProcessHeap(),
|
|
|
|
0,
|
|
|
|
msgLen * sizeof(TCHAR));
|
|
|
|
if (lpFullMsg)
|
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
_snwprintf(lpFullMsg,
|
2008-04-02 16:54:55 +00:00
|
|
|
msgLen,
|
2008-09-01 12:51:49 +00:00
|
|
|
L"%s\r\n",
|
2008-04-02 16:54:55 +00:00
|
|
|
lpMsg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-07 14:09:03 +00:00
|
|
|
/* Make sure the length in bytes doesn't overflow a DWORD */
|
|
|
|
msgLen = wcslen(lpFullMsg);
|
|
|
|
if (msgLen > (MAXDWORD / sizeof(WCHAR)))
|
|
|
|
{
|
|
|
|
RaiseException(EXCEPTION_INT_OVERFLOW, 0, 0, NULL);
|
|
|
|
}
|
|
|
|
|
2008-04-02 16:54:55 +00:00
|
|
|
if (lpFullMsg)
|
|
|
|
{
|
|
|
|
DWORD bytesWritten;
|
2008-09-01 12:51:49 +00:00
|
|
|
DWORD dwRet;
|
|
|
|
BOOL bRet;
|
|
|
|
|
|
|
|
bRet = WriteFile(hLogFile,
|
|
|
|
lpFullMsg,
|
2018-07-07 14:09:03 +00:00
|
|
|
(DWORD)msgLen * sizeof(WCHAR),
|
2008-09-01 12:51:49 +00:00
|
|
|
&bytesWritten,
|
|
|
|
&olWrite);
|
|
|
|
if (!bRet)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-04-02 16:54:55 +00:00
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
if (!bRet || bytesWritten == 0)
|
2008-04-02 16:54:55 +00:00
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
LogToEventLog(L"Failed to write to log file",
|
2008-04-02 16:54:55 +00:00
|
|
|
GetLastError(),
|
|
|
|
0,
|
|
|
|
LOG_EVENTLOG | LOG_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(),
|
|
|
|
0,
|
|
|
|
lpFullMsg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (exitCode > 0)
|
|
|
|
ExitProcess(exitCode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
VOID
|
2008-09-01 12:51:49 +00:00
|
|
|
LogEvent(LPCWSTR lpMsg,
|
2008-04-02 16:54:55 +00:00
|
|
|
DWORD errNum,
|
|
|
|
DWORD exitCode,
|
|
|
|
UINT flags)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG
|
|
|
|
if (flags & LOG_FILE || flags & LOG_ERROR)
|
|
|
|
LogToFile(lpMsg, errNum, exitCode, flags);
|
|
|
|
#endif
|
|
|
|
if (flags & LOG_EVENTLOG)
|
|
|
|
LogToEventLog(lpMsg, errNum, exitCode, flags);
|
|
|
|
}
|
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
BOOL
|
2008-04-02 16:54:55 +00:00
|
|
|
InitLogging()
|
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
#ifdef DEBUG
|
|
|
|
BOOL bRet = FALSE;
|
2008-04-02 16:54:55 +00:00
|
|
|
|
2018-08-28 10:45:03 +00:00
|
|
|
if (!GetEnvironmentVariableW(L"SystemDrive", szLogFileName, ARRAYSIZE(szLogFileName)))
|
|
|
|
{
|
|
|
|
StringCchCopyW(szLogFileName, ARRAYSIZE(szLogFileName), L"C:");
|
|
|
|
}
|
|
|
|
StringCchCatW(szLogFileName, ARRAYSIZE(szLogFileName), L"\\tcpsvcs_log.log");
|
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
ZeroMemory(&olWrite, sizeof(OVERLAPPED));
|
|
|
|
olWrite.Offset = 0xFFFFFFFF;
|
|
|
|
olWrite.OffsetHigh = 0xFFFFFFFF;
|
|
|
|
olWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
if (olWrite.hEvent)
|
2008-04-02 16:54:55 +00:00
|
|
|
{
|
2018-08-28 10:45:03 +00:00
|
|
|
DeleteFileW(szLogFileName);
|
2008-04-02 16:54:55 +00:00
|
|
|
|
2008-09-01 12:51:49 +00:00
|
|
|
if (OpenLogFile())
|
2008-04-02 16:54:55 +00:00
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
WCHAR wcBom = 0xFEFF;
|
|
|
|
DWORD bytesWritten;
|
|
|
|
|
|
|
|
bRet = WriteFile(hLogFile,
|
|
|
|
&wcBom,
|
|
|
|
sizeof(WCHAR),
|
|
|
|
&bytesWritten,
|
|
|
|
&olWrite);
|
|
|
|
if (!bRet)
|
|
|
|
{
|
|
|
|
if (GetLastError() != ERROR_IO_PENDING)
|
|
|
|
{
|
|
|
|
LogToEventLog(L"Failed to write to log file",
|
|
|
|
GetLastError(),
|
|
|
|
0,
|
|
|
|
LOG_EVENTLOG | LOG_ERROR);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bRet = TRUE;
|
|
|
|
}
|
|
|
|
}
|
2008-04-02 16:54:55 +00:00
|
|
|
}
|
|
|
|
}
|
2008-09-01 12:51:49 +00:00
|
|
|
|
|
|
|
return bRet;
|
|
|
|
#else
|
|
|
|
return TRUE;
|
2008-04-02 16:54:55 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
UninitLogging()
|
|
|
|
{
|
2008-09-01 12:51:49 +00:00
|
|
|
if (hLogFile)
|
|
|
|
{
|
|
|
|
FlushFileBuffers(hLogFile);
|
|
|
|
CloseHandle(hLogFile);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (olWrite.hEvent)
|
|
|
|
{
|
|
|
|
CloseHandle(olWrite.hEvent);
|
|
|
|
}
|
2008-04-02 16:54:55 +00:00
|
|
|
}
|