00001
00002
00003
00004
00005 #ifdef WIN32 // only available on Win32
00006
00007 #include <log4cpp/NTEventLogAppender.hh>
00008 #include <log4cpp/FactoryParams.hh>
00009 #include <memory>
00010
00011 namespace log4cpp {
00012
00013 NTEventLogAppender::NTEventLogAppender(const std::string& name, const std::string& sourceName) :
00014 AppenderSkeleton(name),
00015 _strSourceName(sourceName),
00016 _hEventSource(NULL)
00017 {
00018 open();
00019 }
00020
00021 NTEventLogAppender::~NTEventLogAppender()
00022 {
00023 close();
00024 }
00025
00026 void NTEventLogAppender::open()
00027 {
00028 addRegistryInfo(_strSourceName.c_str());
00029 _hEventSource = ::RegisterEventSource(NULL, _strSourceName.c_str());
00030 }
00031
00032 void NTEventLogAppender::close()
00033 {
00034 if (_hEventSource) {
00035 ::DeregisterEventSource(_hEventSource);
00036 }
00037 }
00038
00039 bool NTEventLogAppender::reopen() {
00040 close();
00041 open();
00042 return true;
00043 }
00044
00045 bool NTEventLogAppender::requiresLayout() const {
00046 return false;
00047 }
00048
00049 void NTEventLogAppender::setLayout(Layout* layout) {
00050 return;
00051 }
00052
00053 void NTEventLogAppender::_append(const LoggingEvent& event) {
00054 const char* ps[1];
00055 ps[0] = event.message.c_str();
00056
00057 const DWORD messageID = 0x1000;
00058 ::ReportEvent(_hEventSource, getType(event.priority),
00059 getCategory(event.priority),
00060 messageID, NULL, 1, 0, ps, NULL);
00061 }
00062
00068 WORD NTEventLogAppender::getCategory(Priority::Value priority) {
00069
00070 return (WORD)((priority / 100) + 1);
00071 }
00072
00078 WORD NTEventLogAppender::getType(Priority::Value priority) {
00079
00080 WORD ret_val;
00081
00082 switch (priority) {
00083 case Priority::EMERG:
00084
00085
00086 case Priority::ALERT:
00087 case Priority::CRIT:
00088 case Priority::ERROR:
00089 ret_val = EVENTLOG_ERROR_TYPE;
00090 break;
00091 case Priority::WARN:
00092 ret_val = EVENTLOG_WARNING_TYPE;
00093 break;
00094 case Priority::NOTICE:
00095 case Priority::INFO:
00096 case Priority::DEBUG:
00097 default:
00098 ret_val = EVENTLOG_INFORMATION_TYPE;
00099 break;
00100 }
00101 return ret_val;
00102 }
00103
00104 HKEY NTEventLogAppender::regGetKey(TCHAR *subkey, DWORD *disposition) {
00105 HKEY hkey = 0;
00106 RegCreateKeyEx(HKEY_LOCAL_MACHINE, subkey, 0, NULL,
00107 REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL,
00108 &hkey, disposition);
00109 return hkey;
00110 }
00111
00112 void NTEventLogAppender::regSetString(HKEY hkey, TCHAR *name, TCHAR *value) {
00113 RegSetValueEx(hkey, name, 0, REG_SZ, (LPBYTE)value, lstrlen(value));
00114 }
00115
00116 void NTEventLogAppender::regSetDword(HKEY hkey, TCHAR *name, DWORD value) {
00117 RegSetValueEx(hkey, name, 0, REG_DWORD, (LPBYTE)&value, sizeof(DWORD));
00118 }
00119
00120
00121
00122
00123 void NTEventLogAppender::addRegistryInfo(const char *source) {
00124 const TCHAR *prefix = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\";
00125 DWORD disposition;
00126 HKEY hkey = 0;
00127 TCHAR subkey[256];
00128
00129 lstrcpy(subkey, prefix);
00130 lstrcat(subkey, source);
00131 hkey = regGetKey(subkey, &disposition);
00132 if (disposition == REG_CREATED_NEW_KEY) {
00133 regSetString(hkey, "EventMessageFile", "NTEventLogAppender.dll");
00134 regSetString(hkey, "CategoryMessageFile", "NTEventLogAppender.dll");
00135 regSetDword(hkey, "TypesSupported", (DWORD)7);
00136 regSetDword(hkey, "CategoryCount", (DWORD)8);
00137 }
00138 RegCloseKey(hkey);
00139 return;
00140 }
00141
00142 std::auto_ptr<Appender> create_nt_event_log_appender(const FactoryParams& params)
00143 {
00144 std::string name, source_name;
00145 params.get_for("nt event log appender").required("name", name)("source_name", source_name);
00146
00147 return std::auto_ptr<Appender>(new NTEventLogAppender(name, source_name));
00148 }
00149 }
00150
00151 #endif // WIN32