30 namespace LogOutputWindowsImp
35 std::vector<char> buffer ;
36 std::size_t sizes[] = { 80U , 1024U , 32768U , 0U } ;
37 for( std::size_t * size_p = sizes ; *size_p ; ++size_p )
39 buffer.resize( *size_p+1U ,
'\0' ) ;
40 DWORD size =
static_cast<DWORD
>( buffer.size() ) ;
41 HINSTANCE hinstance = HNULL ;
42 DWORD rc = GetModuleFileNameA( hinstance , &buffer[0] , size ) ;
45 return std::string( &buffer[0] , rc ) ;
47 return std::string() ;
49 std::string basename( std::string s )
51 std::string::size_type pos1 = s.find_last_of(
"\\" ) ;
52 if( pos1 != std::string::npos )
53 s = s.substr( pos1+1U ) ;
54 std::string::size_type pos2 = s.find_last_of(
"." ) ;
55 if( pos2 != std::string::npos )
61 static bool old_windows_set = false ;
62 static bool old_windows = false ;
63 if( !old_windows_set )
65 old_windows_set = true ;
66 old_windows = !IsWindowsVistaOrGreater() ;
73void G::LogOutput::osoutput(
int fd , G::Log::Severity severity ,
char * message , std::size_t n )
77 if( m_config.m_use_syslog &&
78 severity != Log::Severity::Debug &&
79 severity != Log::Severity::InfoVerbose &&
82 DWORD
id = 0x400003E9L ;
83 WORD type = EVENTLOG_INFORMATION_TYPE ;
84 if( severity == Log::Severity::Warning )
87 type = EVENTLOG_WARNING_TYPE ;
89 else if( severity == Log::Severity::Error || severity == Log::Severity::Assertion )
92 type = EVENTLOG_ERROR_TYPE ;
97 if( LogOutputWindowsImp::oldWindows() )
101 const char * p[] = { message ,
nullptr } ;
102 BOOL rc = ReportEventA( m_handle , type , 0 ,
id ,
nullptr , 1 , 0 , p ,
nullptr ) ;
103 GDEF_IGNORE_VARIABLE( rc ) ;
109 if( fd > 2 ) message[n++] =
'\r' ;
110 message[n++] =
'\n' ;
114void G::LogOutput::osinit()
116 if( m_config.m_use_syslog )
118 std::string this_exe = LogOutputWindowsImp::thisExe() ;
119 if( !this_exe.empty() )
121 std::string this_name = LogOutputWindowsImp::basename( this_exe ) ;
123 m_handle = RegisterEventSourceA(
nullptr , this_name.c_str() ) ;
124 if( m_handle == HNULL && !m_config.m_allow_bad_syslog )
125 throw EventLogError() ;
135 std::string reg_path =
136 "SYSTEM\\CurrentControlSet\\services\\eventlog\\Application\\" +
137 LogOutputWindowsImp::basename(exe_path) ;
140 int sam = KEY_WRITE ;
141 LONG e = RegCreateKeyExA( HKEY_LOCAL_MACHINE , reg_path.c_str() , 0 , NULL , 0 , sam , NULL , &key , NULL ) ;
142 if( e == ERROR_SUCCESS && key != 0 )
145 DWORD types = EVENTLOG_INFORMATION_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_ERROR_TYPE ;
146 RegSetValueExA( key ,
"EventMessageFile" , 0 , REG_SZ ,
147 reinterpret_cast<const BYTE*
>(exe_path.c_str()) ,
148 static_cast<DWORD
>(exe_path.length())+1U ) ;
149 RegSetValueExA( key ,
"CategoryCount" , 0 , REG_DWORD ,
150 reinterpret_cast<const BYTE*
>(&one) ,
sizeof(one) ) ;
151 RegSetValueExA( key ,
"CategoryMessageFile" , 0 , REG_SZ ,
152 reinterpret_cast<const BYTE*
>(exe_path.c_str()) ,
153 static_cast<DWORD
>(exe_path.length())+1U ) ;
154 RegSetValueExA( key ,
"TypesSupported" , 0 , REG_DWORD ,
155 reinterpret_cast<const BYTE*
>(&types) ,
sizeof(types) ) ;
161void G::LogOutput::oscleanup() const noexcept
163 if( m_handle != HNULL )
164 DeregisterEventSource( m_handle ) ;
static ssize_t write(int fd, const char *, std::size_t) noexcept
Calls ::write() or equivalent.
static void register_(const std::string &exe)
Registers the given executable as a source of logging.