Class: Win32EventLog
- Inherits:
-
Object
- Object
- Win32EventLog
- Defined in:
- lib/metadata/util/win32/Win32EventLog.rb
Constant Summary collapse
- SYSTEM_LOGS =
Standard file log names
%w(Application System Security)
- BUFFER_READ_SIZE =
10 MB buffer
10485760
- ELF_LOGFILE_HEADER =
Data definitions. (msdn.microsoft.com/en-gb/library/bb309024.aspx)
BinaryStruct.new([ 'L', :header_size, # The size of the header structure. The size is always 0x30. 'a4', :signature, # The signature is always 0x654c664c, which is ASCII for eLfL. 'L', :majorVersion, # The major version number of the event log. The major version number is always set to 1. 'L', :minorVersion, # The minor version number of the event log. The minor version number is always set to 1. 'L', :start_offset, # The offset to the oldest record in the event log. 'L', :end_offset, # The offset to the ELF_EOF_RECORD in the event log. 'L', :current_record_number, # The number of the next record that will be added to the event log. 'L', :oldest_record_number, # The number of the oldest record in the event log. For an empty file, the oldest record number is set to 0. 'L', :max_size, # The maximum size, in bytes, of the event log. The maximum size is defined when the event log is created. # The event-logging service does not typically update this value, it relies on the registry configuration. # The reader of the event log can use normal file APIs to determine the size of the file. 'L', :flags, # See ELF_ below. 'L', :retention, # The retention value of the file when it is created. # The event-logging service does not typically update this value, it relies on the registry configuration. # For more information about registry configuration values, see Eventlog Key. 'L', :end_header_size # The ending size of the header structure. The size is always 0x30. ])
- ELF_DIRTY =
Event Log header flags.
0x00000001
- ELF_WRAPPED =
If set, don’t rely on other values in the header.
0x00000002
- ELF_LOGFULL =
Indicates the log is wrapped.
0x00000004
- ELF_LOGFILE_ARCHIVE_SET =
Set if log full (extended implications in EventLogFormat.txt).
0x00000008
- EVENTLOGEOF =
Data definitions. (msdn.microsoft.com/en-gb/library/bb309022(VS.85).aspx )
BinaryStruct.new([ 'L', :record_size_beginning, # The beginning size of the ELF_EOF_RECORD. The beginning size is always 0x28. 'a16', :magic, # Always \001\001\001\001\002\002\002\002\003\003\003\003\004\004\004\004 'L', :begin_record, # The offset to the oldest record. If the event log is empty, this is set to the start of this structure. 'L', :end_record, # The offset to the start of this structure. 'L', :current_record_number, # The record number of the next event that will be written to the event log. 'L', :oldest_record_number, # The record number of the oldest record in the event log. The record number will be 0 if the event log is empty. 'L', :record_size_end # The ending size of the ELF_EOF_RECORD. The ending size is always 0x28. ])
- EVENTRECORD =
Data definitions. (msdn.microsoft.com/en-gb/library/aa363646(VS.85).aspx)
BinaryStruct.new([ 'L', :record_length, # The size of this event record, in bytes. Note that this value is stored at both ends # of the entry to ease moving forward or backward through the log. The length includes # any pad bytes inserted at the end of the record for DWORD alignment. 'a4', :magic, # A DWORD value that is always set to ELF_LOG_SIGNATURE (the value is 0x654c664c), which is ASCII for eLfL. 'L', :record_num, # The number of the record. 'L', :generated, # The time at which this entry was submitted. This time is measured in the number of seconds elapsed since 00:00:00 January 1, 1970, Universal Coordinated Time. 'L', :written, # The time at which this entry was received by the service to be written to the log. This time is measured in the number of seconds elapsed since 00:00:00 January 1, 1970, Universal Coordinated Time. 'L', :event_id, # The event identifier. The value is specific to the event source for the event, and is used with source name to locate a description string in the message file for the event source 'S', :level, # See EVENTLOG_ below. 'S', :num_strings, # The number of strings present in the log (at the position indicated by StringOffset). These strings are merged into the message before it is displayed to the user. 'S', :category, # The category for this event. The meaning of this value depends on the event source. 'S', :reserved_flags, # Reserved. 'L', :closing_rec_num, # Reserved. 'L', :string_offset, # Offset from beginning of record to UTF-16 strings. 'L', :user_sid_length, # The size of the UserSid member, in bytes. This value can be zero if no security identifier was provided. 'L', :user_sid_offset, # Offset from beginning of record. 'L', :data_length, # Length of parameter data (0 if none). 'L', :data_offset, # The offset of the event-specific information within this event log record, in bytes. # This information could be something specific (a disk driver might log the number of retries, for example), # followed by binary information specific to the event being logged and to the source that generated the entry. ])
- EVENTRECORDLENGTH =
BinaryStruct.new([ 'L', :record_length, # The size of this event record, in bytes. Note that this value is stored at both ends ])
- EVENT_TYPES =
Event types.
{ 0x0000 => :info, # EVENTLOG_SUCCESS 0x0001 => :error, # EVENTLOG_ERROR_TYPE 0x0002 => :warn, # EVENTLOG_WARNING_TYPE 0x0004 => :info, # EVENTLOG_INFORMATION_TYPE 0x0008 => :info, # VENTLOG_AUDIT_SUCCESS 0x0010 => :error, # EVENTLOG_AUDIT_FAILURE }
- MAGIC_HDR =
Magic numbers used by log record types.
"LfLe"
- MAGIC_CSR =
"\x11\x11\x11\x11\x22\x22\x22\x22\x33\x33\x33\x33\x44\x44\x44\x44"
- HKLM =
Registry constants.
0x80000002
- KEY_READ =
0x00020019
- REG_MULTI_SZ =
7
- SIZE_BUF =
Key name buffer size.
256
- INVALID_HANDLE_VALUE =
Misc Windows constants.
-1
- ERROR_SUCCESS =
0
- ERROR_NO_MORE_ITEMS =
259
- FORMAT_TR =
Lookup object for translating the common %? sequences in the messages
Hash.new { |_h, k| k }.merge( '% ' => " ", '%b' => " ", '%.' => ".", '%!' => "!", '%n' => "\r\n", '%r' => "\r", '%t' => "\t", '%0' => "", '!s!' => "" )
- NODE_REC_KEYS =
Keys that will be in the final node record
[:generated, :event_id, :level, :category, :computer_name, :source, :message]
Instance Attribute Summary collapse
-
#customFileName ⇒ Object
readonly
Returns the value of attribute customFileName.
-
#readTimes ⇒ Object
readonly
Returns the value of attribute readTimes.
-
#xmlDoc ⇒ Object
readonly
Returns the value of attribute xmlDoc.
Instance Method Summary collapse
-
#initialize(vmMiqFs = nil) ⇒ Win32EventLog
constructor
A new instance of Win32EventLog.
- #readAllLogs(options) ⇒ Object
- #readLog(log, filter = nil) ⇒ Object
Constructor Details
#initialize(vmMiqFs = nil) ⇒ Win32EventLog
Returns a new instance of Win32EventLog.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/metadata/util/win32/Win32EventLog.rb', line 148 def initialize(vmMiqFs = nil) # vmMiqFs is an MiqFS instance for the file system # of the guest vm if guest logs or nil if host logs. # If an MiqFS instance was not passed, then the OS has to be (or emulate) Win32. # If an MiqFS instance *was* passed, then if the guest OS is not Windows then getSystemRoot will throw. raise "#{self.class}::initialize: Filesystem is not MiqFS: cannot continue" if !vmMiqFs.class.to_s.include?('Miq') # Get a file system instance if we don't already have one. @fs = vmMiqFs @fs = File if @fs.nil? # Init times. @readTimes = {} @msgtbl_cache = {} # Get root, system message tables & init messagetable cache. if @fs == File @systemRoot = 'c:/windows/system32' @kernel32_fn = 'c:/windows/system32/kernel32.dll' else @systemRoot = Win32::SystemPath.systemRoot(@fs) @kernel32_fn = "#{Win32::SystemPath.system32Path(@fs, @systemRoot)}/kernel32.dll" end end |
Instance Attribute Details
#customFileName ⇒ Object (readonly)
Returns the value of attribute customFileName.
145 146 147 |
# File 'lib/metadata/util/win32/Win32EventLog.rb', line 145 def customFileName @customFileName end |
#readTimes ⇒ Object (readonly)
Returns the value of attribute readTimes.
146 147 148 |
# File 'lib/metadata/util/win32/Win32EventLog.rb', line 146 def readTimes @readTimes end |
#xmlDoc ⇒ Object (readonly)
Returns the value of attribute xmlDoc.
145 146 147 |
# File 'lib/metadata/util/win32/Win32EventLog.rb', line 145 def xmlDoc @xmlDoc end |
Instance Method Details
#readAllLogs(options) ⇒ Object
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/metadata/util/win32/Win32EventLog.rb', line 175 def readAllLogs() = .collect { |l| {:name => l, :filter => nil} } if [0].kind_of?(String) .each do |o| start = Time.now readLog(o[:name], o[:filter]) @readTimes[o[:name]] = Time.now - start end @xmlDoc end |
#readLog(log, filter = nil) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/metadata/util/win32/Win32EventLog.rb', line 186 def readLog(log, filter = nil) filter ||= {} EventLogFilter.prepare_filter!(filter) # Get message source files. (This also caches the event log registry entries.) sources = getEventSourceMessageFiles(log) @f = @buf = nil # Get event log file and validate it is a format we support event_file = mkLogPath(log) unless File.extname(event_file).downcase == ".evt" raise MiqException::NtEventLogFormat, "#{self.class}: Unsupported Win32 Eventlog format [#{File.extname(event_file)}] for event log [#{log}]. File:[#{event_file}]" end # Start an XML document recordsNode = mkXmlDoc(log, event_file) getFileObj(event_file) do |f, filename| st = Time.now $log.info "#{self.class}: Opening file for [#{log}]" if $log @f = f @offset = BUFFER_READ_SIZE * -1 hdr = ELF_LOGFILE_HEADER.decode(read_buffer(0, ELF_LOGFILE_HEADER.size)) hdr[:wrapped] = !(hdr[:flags] & ELF_WRAPPED).zero? @file_size = @fs == File ? File.size(filename) : @fs.fileSize(filename) $log.info "#{self.class}: Opened file for [#{log}] in [#{Time.now - st}] seconds. Data Size:[#{@file_size}] Wrapped:[#{hdr[:wrapped]}]" if $log parse_time = Time.now recs_found = 0 recs_processed = 0 @dup_check = {} each_record(hdr, log) do |rec| recs_processed += 1 # Get log record components & filter on them rec[:generated] = Time.at(rec[:generated]).utc.iso8601 break if EventLogFilter.filter_by_generated?(rec[:generated], filter) rec[:level] = EVENT_TYPES[rec[:level]] next if EventLogFilter.filter_by_level?(rec[:level], filter) getSourceName(rec) next if EventLogFilter.filter_by_source?(rec[:source], filter) getStrings(rec) getMessage(log, rec, sources) next if EventLogFilter.(rec[:message], filter) # Get the rest of the record components getComputerName(rec) # There are not presently being used, so there is no need to collect them # rec[:written] = Time.at(rec[:written]).utc.iso8601 # getSID(buf, pos, rec) # getData(buf, pos, rec) # Add the node to the XML recs_found += 1 if addNodeRec(recordsNode, rec) # Quit if we've found enough records break if EventLogFilter.filter_by_rec_count?(recs_found, filter) end # Clean up @dup_check = nil # Store based on log. recordsNode.add_attribute(:num_records, recs_found) $log.info "#{self.class}: Parsed [#{recs_processed}] [#{log}] records in [#{Time.now - parse_time}] seconds. Collected [#{recs_found}] records. Total time [#{Time.now - st}] seconds." if $log end @f = nil end |