add log4cplus
This commit is contained in:
348
libs/log4cplus/src/nteventlogappender.cxx
Normal file
348
libs/log4cplus/src/nteventlogappender.cxx
Normal file
@ -0,0 +1,348 @@
|
||||
// Module: LOG4CPLUS
|
||||
// File: nteventlogappender.cxx
|
||||
// Created: 4/2003
|
||||
// Author: Michael CATANZARITI
|
||||
//
|
||||
// Copyright 2003-2010 Michael CATANZARITI
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <log4cplus/nteventlogappender.h>
|
||||
#include <log4cplus/loglevel.h>
|
||||
#include <log4cplus/streams.h>
|
||||
#include <log4cplus/helpers/loglog.h>
|
||||
#include <log4cplus/spi/loggingevent.h>
|
||||
|
||||
|
||||
#if defined (LOG4CPLUS_HAVE_NT_EVENT_LOG)
|
||||
|
||||
using namespace log4cplus;
|
||||
using namespace log4cplus::spi;
|
||||
using namespace log4cplus::helpers;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// File LOCAL methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace {
|
||||
|
||||
bool
|
||||
FreeSid(SID* pSid)
|
||||
{
|
||||
return ::HeapFree(GetProcessHeap(), 0, (LPVOID)pSid) != 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CopySid(SID** ppDstSid, SID* pSrcSid)
|
||||
{
|
||||
bool bSuccess = false;
|
||||
|
||||
DWORD dwLength = ::GetLengthSid(pSrcSid);
|
||||
*ppDstSid = (SID *) ::HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY, dwLength);
|
||||
|
||||
if(::CopySid(dwLength, *ppDstSid, pSrcSid)) {
|
||||
bSuccess = true;
|
||||
}
|
||||
else {
|
||||
FreeSid(*ppDstSid);
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
GetCurrentUserSID(SID** ppSid)
|
||||
{
|
||||
bool bSuccess = false;
|
||||
|
||||
// Pseudohandle so don't need to close it
|
||||
HANDLE hProcess = ::GetCurrentProcess();
|
||||
HANDLE hToken = NULL;
|
||||
if(::OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) {
|
||||
// Get the required size
|
||||
DWORD tusize = 0;
|
||||
GetTokenInformation(hToken, TokenUser, NULL, 0, &tusize);
|
||||
TOKEN_USER* ptu = (TOKEN_USER*)new BYTE[tusize];
|
||||
|
||||
if(GetTokenInformation(hToken, TokenUser, (LPVOID)ptu, tusize, &tusize)) {
|
||||
bSuccess = CopySid(ppSid, (SID *)ptu->User.Sid);
|
||||
}
|
||||
|
||||
CloseHandle(hToken);
|
||||
delete [] ptu;
|
||||
}
|
||||
|
||||
return bSuccess;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
HKEY
|
||||
regGetKey(const log4cplus::tstring& subkey, DWORD* disposition)
|
||||
{
|
||||
HKEY hkey = 0;
|
||||
RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
||||
subkey.c_str(),
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_SET_VALUE,
|
||||
NULL,
|
||||
&hkey,
|
||||
disposition);
|
||||
return hkey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
regSetString(HKEY hkey, const log4cplus::tstring& name, const log4cplus::tstring& value)
|
||||
{
|
||||
RegSetValueEx(hkey,
|
||||
name.c_str(),
|
||||
0,
|
||||
REG_SZ,
|
||||
(LPBYTE)value.c_str(),
|
||||
static_cast<DWORD>(value.length() * sizeof(tchar)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
regSetDword(HKEY hkey, const log4cplus::tstring& name, DWORD value)
|
||||
{
|
||||
RegSetValueEx(hkey,
|
||||
name.c_str(),
|
||||
0,
|
||||
REG_DWORD,
|
||||
(LPBYTE)&value,
|
||||
sizeof(DWORD));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// log4cplus::NTEventLogAppender ctor and dtor
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NTEventLogAppender::NTEventLogAppender(const log4cplus::tstring& server,
|
||||
const log4cplus::tstring& log,
|
||||
const log4cplus::tstring& source)
|
||||
: server(server),
|
||||
log(log),
|
||||
source(source),
|
||||
hEventLog(NULL),
|
||||
pCurrentUserSID(NULL)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTEventLogAppender::NTEventLogAppender(const Properties properties)
|
||||
: Appender(properties),
|
||||
hEventLog(NULL),
|
||||
pCurrentUserSID(NULL)
|
||||
{
|
||||
server = properties.getProperty( LOG4CPLUS_TEXT("server") );
|
||||
log = properties.getProperty( LOG4CPLUS_TEXT("log") );
|
||||
source = properties.getProperty( LOG4CPLUS_TEXT("source") );
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
NTEventLogAppender::init()
|
||||
{
|
||||
if(source.empty()) {
|
||||
getLogLog().warn( LOG4CPLUS_TEXT("Source option not set for appender [")
|
||||
+ name
|
||||
+ LOG4CPLUS_TEXT("]."));
|
||||
return;
|
||||
}
|
||||
|
||||
if(log.empty ()) {
|
||||
log = LOG4CPLUS_TEXT("Application");
|
||||
}
|
||||
|
||||
// current user security identifier
|
||||
GetCurrentUserSID(&pCurrentUserSID);
|
||||
|
||||
addRegistryInfo();
|
||||
|
||||
hEventLog = ::RegisterEventSource(server.empty () ? 0 : server.c_str(),
|
||||
source.c_str());
|
||||
if (! hEventLog || hEventLog == HANDLE(ERROR_INVALID_HANDLE))
|
||||
getLogLog().warn (LOG4CPLUS_TEXT("Event source registration failed."));
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTEventLogAppender::~NTEventLogAppender()
|
||||
{
|
||||
destructorImpl();
|
||||
|
||||
if(pCurrentUserSID != NULL) {
|
||||
FreeSid(pCurrentUserSID);
|
||||
pCurrentUserSID = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// log4cplus::NTEventLogAppender public methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
NTEventLogAppender::close()
|
||||
{
|
||||
if(hEventLog != NULL) {
|
||||
::DeregisterEventSource(hEventLog);
|
||||
hEventLog = NULL;
|
||||
}
|
||||
closed = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// log4cplus::NTEventLogAppender protected methods
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
NTEventLogAppender::append(const InternalLoggingEvent& event)
|
||||
{
|
||||
if(hEventLog == NULL) {
|
||||
getLogLog().warn(LOG4CPLUS_TEXT("NT EventLog not opened."));
|
||||
return;
|
||||
}
|
||||
|
||||
tostringstream buf;
|
||||
layout->formatAndAppend(buf, event);
|
||||
tstring sz = buf.str();
|
||||
const tchar * s = sz.c_str();
|
||||
|
||||
BOOL bSuccess = ::ReportEvent(hEventLog,
|
||||
getEventType(event),
|
||||
getEventCategory(event),
|
||||
0x1000,
|
||||
pCurrentUserSID,
|
||||
1,
|
||||
0,
|
||||
&s,
|
||||
NULL);
|
||||
|
||||
if(!bSuccess) {
|
||||
getLogLog().error(LOG4CPLUS_TEXT("Cannot report event in NT EventLog."));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
WORD
|
||||
NTEventLogAppender::getEventType(const InternalLoggingEvent& event)
|
||||
{
|
||||
WORD ret_val;
|
||||
|
||||
switch ((int)event.getLogLevel())
|
||||
{
|
||||
case FATAL_LOG_LEVEL:
|
||||
case ERROR_LOG_LEVEL:
|
||||
ret_val = EVENTLOG_ERROR_TYPE;
|
||||
break;
|
||||
case WARN_LOG_LEVEL:
|
||||
ret_val = EVENTLOG_WARNING_TYPE;
|
||||
break;
|
||||
case INFO_LOG_LEVEL:
|
||||
case DEBUG_LOG_LEVEL:
|
||||
default:
|
||||
ret_val = EVENTLOG_INFORMATION_TYPE;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
WORD
|
||||
NTEventLogAppender::getEventCategory(const InternalLoggingEvent& event)
|
||||
{
|
||||
WORD ret_val;
|
||||
|
||||
switch (event.getLogLevel())
|
||||
{
|
||||
case FATAL_LOG_LEVEL:
|
||||
ret_val = 1;
|
||||
break;
|
||||
case ERROR_LOG_LEVEL:
|
||||
ret_val = 2;
|
||||
break;
|
||||
case WARN_LOG_LEVEL:
|
||||
ret_val = 3;
|
||||
break;
|
||||
case INFO_LOG_LEVEL:
|
||||
ret_val = 4;
|
||||
break;
|
||||
case DEBUG_LOG_LEVEL:
|
||||
default:
|
||||
ret_val = 5;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
// Add this source with appropriate configuration keys to the registry.
|
||||
void
|
||||
NTEventLogAppender::addRegistryInfo()
|
||||
{
|
||||
DWORD disposition;
|
||||
HKEY hkey = 0;
|
||||
tstring subkey = LOG4CPLUS_TEXT("SYSTEM\\CurrentControlSet\\Services\\EventLog\\")
|
||||
+ log
|
||||
+ LOG4CPLUS_TEXT("\\")
|
||||
+ source;
|
||||
|
||||
hkey = regGetKey(subkey, &disposition);
|
||||
if(disposition == REG_CREATED_NEW_KEY) {
|
||||
regSetString(hkey,
|
||||
LOG4CPLUS_TEXT("EventMessageFile"),
|
||||
LOG4CPLUS_TEXT("NTEventLogAppender.dll"));
|
||||
regSetString(hkey,
|
||||
LOG4CPLUS_TEXT("CategoryMessageFile"),
|
||||
LOG4CPLUS_TEXT("NTEventLogAppender.dll"));
|
||||
regSetDword(hkey, LOG4CPLUS_TEXT("TypesSupported"), (DWORD)7);
|
||||
regSetDword(hkey, LOG4CPLUS_TEXT("CategoryCount"), (DWORD)5);
|
||||
}
|
||||
|
||||
RegCloseKey(hkey);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user