GitHub Actions: Try MSVC builds with /std:c++17 and 20
[ACE_TAO.git] / ACE / ace / Log_Msg_NT_Event_Log.cpp
blobf9d0d141deb9368a9892ee5ae05d4e5dfc622633
1 #include "ace/config-all.h"
3 #if defined (ACE_HAS_LOG_MSG_NT_EVENT_LOG)
5 #include "ace/Log_Msg_NT_Event_Log.h"
6 #include "ace/Log_Category.h"
7 #include "ace/Log_Record.h"
8 #include "ace/OS_NS_stdio.h"
9 #include "ace/OS_NS_string.h"
13 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 ACE_Log_Msg_NT_Event_Log::ACE_Log_Msg_NT_Event_Log (void)
16 : evlog_handle_(0)
20 ACE_Log_Msg_NT_Event_Log::~ACE_Log_Msg_NT_Event_Log (void)
22 this->close ();
25 int
26 ACE_Log_Msg_NT_Event_Log::open (const ACE_TCHAR *logger_key)
28 // ACE's "resource module" contains the message resource required
29 // for event logging.
30 ACE_TCHAR msg_file [MAXPATHLEN];
32 if (!ACE_TEXT_GetModuleFileName (ACE_OS::get_win32_resource_module (),
33 msg_file,
34 MAXPATHLEN))
35 return -1;
36 DWORD msg_file_length =
37 static_cast<DWORD> ((ACE_OS::strlen (msg_file) + 1) * sizeof (ACE_TCHAR));
39 // If a logger_key has been supplied then we use that as the event
40 // source name, otherwise we default to the program name.
41 const ACE_TCHAR *event_source_name = logger_key ? logger_key : ACE_Log_Msg::program_name ();
43 // Information is stored in the registry at a location based on the
44 // program name.
45 ACE_TCHAR reg_key [MAXPATHLEN];
46 ACE_OS::strcpy (reg_key,
47 ACE_TEXT ("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"));
48 size_t reg_key_length = ACE_OS::strlen(reg_key);
49 ACE_OS::strncat (reg_key,
50 event_source_name,
51 MAXPATHLEN - reg_key_length);
53 // Add the event source to the registry. Note that if this fails it
54 // is not fatal. The application will still be able to write entries
55 // to the event log, they just won't be formatted correctly.
56 HKEY hkey;
57 ACE_TEXT_RegCreateKey (HKEY_LOCAL_MACHINE,
58 reg_key,
59 &hkey);
60 DWORD flags = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE;
61 ACE_TEXT_RegSetValueEx (hkey,
62 ACE_TEXT ("TypesSupported"),
64 REG_DWORD,
65 (LPBYTE) &flags,
66 sizeof (DWORD));
67 ACE_TEXT_RegSetValueEx (hkey,
68 ACE_TEXT ("EventMessageFile"),
70 REG_SZ,
71 (LPBYTE) msg_file,
72 msg_file_length);
73 RegCloseKey (hkey);
75 // Obtain a handle to the event source.
76 this->evlog_handle_ = ACE_TEXT_RegisterEventSource (0,
77 event_source_name);
78 return this->evlog_handle_ ? 0 : -1;
81 int
82 ACE_Log_Msg_NT_Event_Log::reset (void)
84 return this->close ();
87 int
88 ACE_Log_Msg_NT_Event_Log::close (void)
90 if (this->evlog_handle_ == 0
91 || DeregisterEventSource (this->evlog_handle_))
93 this->evlog_handle_ = 0;
94 return 0;
96 else
97 return -1;
100 ssize_t
101 ACE_Log_Msg_NT_Event_Log::log (ACE_Log_Record &log_record)
103 // Make a copy of the log text and replace any newlines with
104 // CR-LF. Newline characters on their own do not appear correctly in
105 // the event viewer. We allow for a doubling in the size of the msg
106 // data for the worst case of all newlines.
107 const ACE_TCHAR *src_msg_data = log_record.msg_data ();
108 ACE_TCHAR msg_data [(ACE_Log_Record::MAXLOGMSGLEN * 2) + 1];
110 size_t maxlen = ACE_Log_Record::MAXLOGMSGLEN;
111 if (ACE_Log_Record::MAXLOGMSGLEN > log_record.msg_data_len ())
112 maxlen = log_record.msg_data_len ();
114 size_t end = 0;
115 for (size_t i = 0, j = 0;
116 i < maxlen;
117 ++i)
119 if (src_msg_data[i] == '\n')
121 msg_data[j++] = '\r';
122 msg_data[j++] = '\n';
124 else
125 msg_data[j++] = src_msg_data[i];
127 end = j;
129 msg_data[end] = '\0';
131 // Map the ACE log record type to an event log type.
132 WORD event_type;
133 switch (log_record.type ())
135 case LM_STARTUP:
136 case LM_SHUTDOWN:
137 case LM_TRACE:
138 case LM_DEBUG:
139 case LM_INFO:
140 event_type = EVENTLOG_INFORMATION_TYPE;
141 break;
142 case LM_NOTICE:
143 case LM_WARNING:
144 event_type = EVENTLOG_WARNING_TYPE;
145 break;
146 case LM_ERROR:
147 case LM_CRITICAL:
148 case LM_ALERT:
149 case LM_EMERGENCY:
150 default:
151 event_type = EVENTLOG_ERROR_TYPE;
152 break;
155 // Send the log message to the system event log.
156 const ACE_TCHAR* msgs [1];
157 msgs[0] = msg_data;
159 if (ACE_TEXT_ReportEvent (this->evlog_handle_,
160 event_type, 0, 0, 0, 1, 0, msgs, 0) == 0)
161 return -1;
162 else
163 return 0;
166 ACE_END_VERSIONED_NAMESPACE_DECL
168 #endif /* ACE_HAS_LOG_MSG_NT_EVENT_LOG */