win32-eventlog 0.5.2 → 0.5.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -2
- data/README +42 -47
- data/Rakefile +51 -32
- data/lib/win32/eventlog.rb +192 -187
- data/misc/install_msg.rb +19 -21
- data/test/test_eventlog.rb +282 -199
- data/win32-eventlog.gemspec +23 -27
- metadata +49 -21
data/CHANGES
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
== 0.5.3 - 26-Oct-2011
|
2
|
+
* Fixed the String#nstrip method for Ruby 1.9.x. Thanks go to Jason Bourne
|
3
|
+
for the spot and Ben Jansen for the patch.
|
4
|
+
* Refactored the Rakefile and tests.
|
5
|
+
|
1
6
|
== 0.5.2 - 21-Aug-2009
|
2
7
|
* EventLogStruct's are now frozen on read operations. This is read-only data.
|
3
8
|
* Added a test to validate that structs are frozen.
|
@@ -103,7 +108,7 @@
|
|
103
108
|
* Added the EventLog#full? method.
|
104
109
|
* Documentation updates and corrections, including the tutorial on creating
|
105
110
|
and writing to your own event source.
|
106
|
-
|
111
|
+
|
107
112
|
== 0.3.3 - 2-Jan-2006
|
108
113
|
* If EventLog.new fails, it now raises EventLogError instead of StandardError.
|
109
114
|
* Added documentation to the eventlog.txt file for EventLog#notify_change.
|
@@ -129,7 +134,7 @@
|
|
129
134
|
no block is given.
|
130
135
|
* Added the 'rubymsg.mc' message category file. If installed, this will
|
131
136
|
create a 'RubyMsg' event source for use with win32-service, though you
|
132
|
-
may use it for whatever you wish. See the README for more details.
|
137
|
+
may use it for whatever you wish. See the README for more details.
|
133
138
|
* Renamed struct back to EventLogStruct - sorry, sorry - I promise I won't
|
134
139
|
change this again.
|
135
140
|
* Fixed a bug where using EventLog::SEEK_READ did not work properly (thanks
|
data/README
CHANGED
@@ -1,73 +1,68 @@
|
|
1
1
|
== Description
|
2
|
-
|
3
|
-
|
2
|
+
The win32-eventlog library provides an interface for reading from and
|
3
|
+
writing to the MS Windows Event Log.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
In addition, you can create your own message event sources using the
|
6
|
+
win32-mc library (provided with this distro), assuming you have the
|
7
|
+
proper tools installed.
|
8
8
|
|
9
9
|
== Prerequisites
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
writing to an existing event log.
|
10
|
+
windows-pr 0.9.3 or later.
|
11
|
+
|
12
|
+
The 'mc', 'rc' and 'link' command line tools are required to create and
|
13
|
+
install message sources. You won't need these for simply reading from or
|
14
|
+
writing to an existing event log.
|
16
15
|
|
17
16
|
== Installation
|
18
|
-
|
19
|
-
gem install win32-eventlog
|
20
|
-
=== Local Installation
|
21
|
-
rake test (optional)
|
22
|
-
rake install (non-gem) or rake install_gem (gem)
|
17
|
+
gem install win32-eventlog
|
23
18
|
|
24
19
|
=== General Installation Notes
|
25
|
-
|
26
|
-
|
27
|
-
|
20
|
+
This will install both the win32-eventlog and win32-mc libraries. The latter
|
21
|
+
is strictly for turning .mc files into .dll files. See the mc documentation
|
22
|
+
for more details.
|
28
23
|
|
29
24
|
== Installing the 'RubyMsg' event source
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
25
|
+
If you wish to install the RubyMsg event source then run the
|
26
|
+
event_source:install Rake task. This will create a 'rubymsg' directory
|
27
|
+
under your toplevel Ruby installation directory (usually C:\ruby), and
|
28
|
+
create the .dll, .h, .rc and .res files there, in addition to copying the
|
29
|
+
rubymsg.mc file. It will then install the 'RubyMsg' event source into your
|
30
|
+
registry.
|
36
31
|
|
37
|
-
|
38
|
-
|
32
|
+
DO NOT MOVE THE DLL FILE ONCE IT IS INSTALLED! If you do, you will have
|
33
|
+
to delete the registry entry and reinstall it with the correct path.
|
39
34
|
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
Take a look at the rubymsg.mc file for the category and message values. If
|
36
|
+
you do not understand this, please read the 'tutorial.txt' file in the 'doc'
|
37
|
+
directory.
|
43
38
|
|
44
39
|
== Additional documentation
|
45
|
-
|
46
|
-
|
40
|
+
If you are unfamiliar with message files and event logging on Windows in
|
41
|
+
general, please read the 'tutorial.txt' file.
|
47
42
|
|
48
|
-
|
49
|
-
|
43
|
+
There are also a couple of sample test scripts under the 'examples'
|
44
|
+
directory if you want to futz around and get a feel for how things work.
|
50
45
|
|
51
46
|
== If the test_mc.rb tests are skipped
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
47
|
+
If the tests from the test_mc.rb file are omitted then you either don't
|
48
|
+
have the mc, rc and/or link commands installed or they're not in your
|
49
|
+
system's %PATH%. If you have MSVC++, you should have them somewhere on your
|
50
|
+
system.
|
56
51
|
|
57
52
|
== Known Issues
|
58
|
-
|
53
|
+
None known.
|
59
54
|
|
60
|
-
|
61
|
-
|
55
|
+
Please file any bug reports on the project page at
|
56
|
+
http://www.rubyforge.org/projects/win32utils.
|
62
57
|
|
63
58
|
== License
|
64
|
-
|
59
|
+
Artistic 2.0
|
65
60
|
|
66
61
|
== Warranty
|
67
|
-
|
68
|
-
|
69
|
-
|
62
|
+
This package is provided "as is" and without any express or
|
63
|
+
implied warranties, including, without limitation, the implied
|
64
|
+
warranties of merchantability and fitness for a particular purpose.
|
70
65
|
|
71
66
|
== Authors
|
72
|
-
|
73
|
-
|
67
|
+
Daniel J. Berger
|
68
|
+
Park Heesob
|
data/Rakefile
CHANGED
@@ -1,46 +1,65 @@
|
|
1
1
|
require 'rake'
|
2
|
+
require 'rake/clean'
|
2
3
|
require 'rake/testtask'
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
5
|
+
CLEAN.include('**/*.gem', '**/*.rbc')
|
6
|
+
|
7
|
+
namespace :gem do
|
8
|
+
desc 'Create the win32-eventlog gem'
|
9
|
+
task :create => [:clean] do
|
10
|
+
spec = eval(IO.read('win32-eventlog.gemspec'))
|
11
|
+
Gem::Builder.new(spec).build
|
12
|
+
end
|
11
13
|
|
12
|
-
desc 'Install the win32-eventlog
|
13
|
-
task :
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
desc 'Install the win32-eventlog gem'
|
15
|
+
task :install => [:create] do
|
16
|
+
ruby 'win32-eventlog.gemspec'
|
17
|
+
file = Dir["*.gem"].first
|
18
|
+
sh "gem install #{file}"
|
19
|
+
end
|
17
20
|
end
|
18
21
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
namespace :example do
|
23
|
+
desc 'Run the notify (tail) example program'
|
24
|
+
task :notify do
|
25
|
+
ruby '-Ilib examples/example_notify.rb'
|
26
|
+
end
|
22
27
|
|
23
|
-
desc 'Run the read example program'
|
24
|
-
task :
|
25
|
-
|
28
|
+
desc 'Run the read example program'
|
29
|
+
task :read do
|
30
|
+
ruby '-Ilib examples/example_read.rb'
|
31
|
+
end
|
26
32
|
|
27
|
-
desc 'Run the write example program'
|
28
|
-
task :
|
29
|
-
|
33
|
+
desc 'Run the write example program'
|
34
|
+
task :write do
|
35
|
+
ruby '-Ilib examples/example_write.rb'
|
36
|
+
end
|
37
|
+
end
|
30
38
|
|
31
|
-
|
32
|
-
|
33
|
-
|
39
|
+
namespace :event_source do
|
40
|
+
desc 'Install the RubyMsg event source'
|
41
|
+
task :install do
|
42
|
+
sh "ruby -Ilib misc/install_msg.rb"
|
43
|
+
end
|
34
44
|
end
|
35
45
|
|
36
|
-
Rake::TestTask.new
|
37
|
-
|
38
|
-
|
39
|
-
t.test_files = Dir['test/test_eventlog.rb']
|
46
|
+
Rake::TestTask.new do |t|
|
47
|
+
t.warning = true
|
48
|
+
t.verbose = true
|
40
49
|
end
|
41
50
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
51
|
+
namespace :test do
|
52
|
+
Rake::TestTask.new(:eventlog) do |t|
|
53
|
+
t.warning = true
|
54
|
+
t.verbose = true
|
55
|
+
t.test_files = Dir['test/test_eventlog.rb']
|
56
|
+
end
|
57
|
+
|
58
|
+
Rake::TestTask.new(:mc) do |t|
|
59
|
+
t.warning = true
|
60
|
+
t.verbose = true
|
61
|
+
t.test_files = Dir['test/test_mc.rb']
|
62
|
+
end
|
46
63
|
end
|
64
|
+
|
65
|
+
task :default => :test
|
data/lib/win32/eventlog.rb
CHANGED
@@ -8,11 +8,16 @@ require 'windows/synchronize'
|
|
8
8
|
require 'windows/handle'
|
9
9
|
|
10
10
|
class String
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
11
|
+
# Return the portion of the string up to the first NULL character. This
|
12
|
+
# was added for both speed and convenience.
|
13
|
+
def nstrip
|
14
|
+
if RUBY_VERSION.to_f >= 1.9
|
15
|
+
unless self.ascii_only?
|
16
|
+
self.force_encoding('BINARY')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
self[ /^[^\0]*/ ]
|
20
|
+
end
|
16
21
|
end
|
17
22
|
|
18
23
|
# The Win32 module serves as a namespace only.
|
@@ -21,11 +26,11 @@ module Win32
|
|
21
26
|
# The EventLog class encapsulates an Event Log source and provides methods
|
22
27
|
# for interacting with that source.
|
23
28
|
class EventLog
|
24
|
-
|
29
|
+
|
25
30
|
# The EventLog::Error is raised in cases where interaction with the
|
26
31
|
# event log should happen to fail for any reason.
|
27
32
|
class Error < StandardError; end
|
28
|
-
|
33
|
+
|
29
34
|
include Windows::Error
|
30
35
|
include Windows::EventLog
|
31
36
|
include Windows::Security
|
@@ -36,10 +41,10 @@ module Win32
|
|
36
41
|
include Windows::Handle
|
37
42
|
extend Windows::Error
|
38
43
|
extend Windows::Registry
|
39
|
-
|
44
|
+
|
40
45
|
# The version of the win32-eventlog library
|
41
|
-
VERSION = '0.5.
|
42
|
-
|
46
|
+
VERSION = '0.5.3'
|
47
|
+
|
43
48
|
# The log is read in chronological order, i.e. oldest to newest.
|
44
49
|
FORWARDS_READ = EVENTLOG_FORWARDS_READ
|
45
50
|
|
@@ -55,7 +60,7 @@ module Win32
|
|
55
60
|
SEQUENTIAL_READ = EVENTLOG_SEQUENTIAL_READ
|
56
61
|
|
57
62
|
# Event types
|
58
|
-
|
63
|
+
|
59
64
|
# Information event, an event that describes the successful operation
|
60
65
|
# of an application, driver or service.
|
61
66
|
SUCCESS = EVENTLOG_SUCCESS
|
@@ -81,72 +86,72 @@ module Win32
|
|
81
86
|
AUDIT_FAILURE = EVENTLOG_AUDIT_FAILURE
|
82
87
|
|
83
88
|
private
|
84
|
-
|
89
|
+
|
85
90
|
# :stopdoc:
|
86
|
-
|
91
|
+
|
87
92
|
BUFFER_SIZE = 1024 * 64
|
88
93
|
MAX_SIZE = 256
|
89
94
|
MAX_STRINGS = 16
|
90
95
|
BASE_KEY = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"
|
91
|
-
|
96
|
+
|
92
97
|
# :startdoc:
|
93
98
|
|
94
99
|
public
|
95
|
-
|
100
|
+
|
96
101
|
# The EventLogStruct encapsulates a single event log record.
|
97
102
|
EventLogStruct = Struct.new('EventLogStruct', :record_number,
|
98
103
|
:time_generated, :time_written, :event_id, :event_type, :category,
|
99
104
|
:source, :computer, :user, :string_inserts, :description
|
100
105
|
)
|
101
|
-
|
106
|
+
|
102
107
|
# The name of the event log source. This will typically be
|
103
108
|
# 'Application', 'System' or 'Security', but could also refer to
|
104
109
|
# a custom event log source.
|
105
|
-
#
|
110
|
+
#
|
106
111
|
attr_reader :source
|
107
|
-
|
112
|
+
|
108
113
|
# The name of the server which the event log is reading from.
|
109
|
-
#
|
114
|
+
#
|
110
115
|
attr_reader :server
|
111
|
-
|
116
|
+
|
112
117
|
# The name of the file used in the EventLog.open_backup method. This is
|
113
118
|
# set to nil if the file was not opened using the EventLog.open_backup
|
114
119
|
# method.
|
115
|
-
#
|
120
|
+
#
|
116
121
|
attr_reader :file
|
117
|
-
|
122
|
+
|
118
123
|
# Opens a handle to the new EventLog +source+ on +server+, or the local
|
119
124
|
# machine if no host is specified. Typically, your source will be
|
120
125
|
# 'Application, 'Security' or 'System', although you can specify a
|
121
126
|
# custom log file as well.
|
122
|
-
#
|
127
|
+
#
|
123
128
|
# If a custom, registered log file name cannot be found, the event
|
124
129
|
# logging service opens the 'Application' log file. This is the
|
125
130
|
# behavior of the underlying Windows function, not my own doing.
|
126
|
-
#
|
131
|
+
#
|
127
132
|
def initialize(source = 'Application', server = nil, file = nil)
|
128
133
|
@source = source || 'Application' # In case of explicit nil
|
129
134
|
@server = server
|
130
135
|
@file = file
|
131
|
-
|
136
|
+
|
132
137
|
# Avoid potential segfaults from win32-api
|
133
138
|
raise TypeError unless @source.is_a?(String)
|
134
139
|
raise TypeError unless @server.is_a?(String) if @server
|
135
|
-
|
140
|
+
|
136
141
|
function = 'OpenEventLog()'
|
137
|
-
|
142
|
+
|
138
143
|
if @file.nil?
|
139
144
|
@handle = OpenEventLog(@server, @source)
|
140
145
|
else
|
141
146
|
@handle = OpenBackupEventLog(@server, @file)
|
142
147
|
function = 'OpenBackupEventLog()'
|
143
148
|
end
|
144
|
-
|
149
|
+
|
145
150
|
if @handle == 0
|
146
151
|
error = "#{function} failed: " + get_last_error
|
147
152
|
raise Error, error
|
148
153
|
end
|
149
|
-
|
154
|
+
|
150
155
|
# Ensure the handle is closed at the end of a block
|
151
156
|
if block_given?
|
152
157
|
begin
|
@@ -156,33 +161,33 @@ module Win32
|
|
156
161
|
end
|
157
162
|
end
|
158
163
|
end
|
159
|
-
|
164
|
+
|
160
165
|
# Class method aliases
|
161
166
|
class << self
|
162
167
|
alias :open :new
|
163
168
|
end
|
164
|
-
|
169
|
+
|
165
170
|
# Nearly identical to EventLog.open, except that the source is a backup
|
166
171
|
# file and not an event source (and there is no default).
|
167
|
-
#
|
172
|
+
#
|
168
173
|
def self.open_backup(file, source = 'Application', server = nil, &block)
|
169
174
|
@file = file
|
170
175
|
@source = source
|
171
176
|
@server = server
|
172
|
-
|
177
|
+
|
173
178
|
# Avoid potential segfaults from win32-api
|
174
179
|
raise TypeError unless @file.is_a?(String)
|
175
180
|
raise TypeError unless @source.is_a?(String)
|
176
|
-
raise TypeError unless @server.is_a?(String) if @server
|
181
|
+
raise TypeError unless @server.is_a?(String) if @server
|
177
182
|
|
178
183
|
self.new(source, server, file, &block)
|
179
184
|
end
|
180
|
-
|
185
|
+
|
181
186
|
# Adds an event source to the registry. Returns the disposition, which
|
182
187
|
# is either REG_CREATED_NEW_KEY (1) or REG_OPENED_EXISTING_KEY (2).
|
183
188
|
#
|
184
189
|
# The following are valid keys:
|
185
|
-
#
|
190
|
+
#
|
186
191
|
# * source # Source name. Set to "Application" by default
|
187
192
|
# * key_name # Name stored as the registry key
|
188
193
|
# * category_count # Number of supported (custom) categories
|
@@ -201,10 +206,10 @@ module Win32
|
|
201
206
|
# The +event_message_file+ and +category_message_file+ are typically,
|
202
207
|
# though not necessarily, the same file. See the documentation on .mc files
|
203
208
|
# for more details.
|
204
|
-
#
|
209
|
+
#
|
205
210
|
def self.add_event_source(args)
|
206
211
|
raise TypeError unless args.is_a?(Hash)
|
207
|
-
|
212
|
+
|
208
213
|
valid_keys = %w/
|
209
214
|
source
|
210
215
|
key_name
|
@@ -222,8 +227,8 @@ module Win32
|
|
222
227
|
'source' => 'Application',
|
223
228
|
'supported_types' => ERROR | WARN | INFO
|
224
229
|
}
|
225
|
-
|
226
|
-
# Validate the keys, and convert symbols and case to lowercase strings.
|
230
|
+
|
231
|
+
# Validate the keys, and convert symbols and case to lowercase strings.
|
227
232
|
args.each{ |key, val|
|
228
233
|
key = key.to_s.downcase
|
229
234
|
unless valid_keys.include?(key)
|
@@ -231,17 +236,17 @@ module Win32
|
|
231
236
|
end
|
232
237
|
hash[key] = val
|
233
238
|
}
|
234
|
-
|
239
|
+
|
235
240
|
# The key_name must be specified
|
236
241
|
unless hash['key_name']
|
237
242
|
raise Error, 'no event_type specified'
|
238
243
|
end
|
239
|
-
|
240
|
-
hkey = [0].pack('L')
|
244
|
+
|
245
|
+
hkey = [0].pack('L')
|
241
246
|
key = key_base + hash['source']
|
242
|
-
|
247
|
+
|
243
248
|
disposition = [0].pack('L')
|
244
|
-
|
249
|
+
|
245
250
|
rv = RegCreateKeyEx(
|
246
251
|
HKEY_LOCAL_MACHINE,
|
247
252
|
key,
|
@@ -252,16 +257,16 @@ module Win32
|
|
252
257
|
nil,
|
253
258
|
hkey,
|
254
259
|
disposition
|
255
|
-
)
|
256
|
-
|
260
|
+
)
|
261
|
+
|
257
262
|
if rv != ERROR_SUCCESS
|
258
263
|
error = 'RegCreateKeyEx() failed: ' + get_last_error
|
259
264
|
raise Error, error
|
260
265
|
end
|
261
|
-
|
262
|
-
hkey = hkey.unpack('L')[0]
|
266
|
+
|
267
|
+
hkey = hkey.unpack('L')[0]
|
263
268
|
data = "%SystemRoot%\\System32\\config\\#{hash['source']}.evt"
|
264
|
-
|
269
|
+
|
265
270
|
begin
|
266
271
|
rv = RegSetValueEx(
|
267
272
|
hkey,
|
@@ -271,20 +276,20 @@ module Win32
|
|
271
276
|
data,
|
272
277
|
data.size
|
273
278
|
)
|
274
|
-
|
279
|
+
|
275
280
|
if rv != ERROR_SUCCESS
|
276
281
|
error = 'RegSetValueEx() failed: ', get_last_error
|
277
282
|
raise Error, error
|
278
283
|
end
|
279
284
|
ensure
|
280
|
-
RegCloseKey(hkey)
|
285
|
+
RegCloseKey(hkey)
|
281
286
|
end
|
282
|
-
|
287
|
+
|
283
288
|
hkey = [0].pack('L')
|
284
289
|
key = key_base << hash['source'] << "\\" << hash['key_name']
|
285
|
-
|
290
|
+
|
286
291
|
disposition = [0].pack('L')
|
287
|
-
|
292
|
+
|
288
293
|
begin
|
289
294
|
rv = RegCreateKeyEx(
|
290
295
|
HKEY_LOCAL_MACHINE,
|
@@ -297,16 +302,16 @@ module Win32
|
|
297
302
|
hkey,
|
298
303
|
disposition
|
299
304
|
)
|
300
|
-
|
305
|
+
|
301
306
|
if rv != ERROR_SUCCESS
|
302
307
|
raise Error, 'RegCreateKeyEx() failed: ' + get_last_error
|
303
308
|
end
|
304
|
-
|
309
|
+
|
305
310
|
hkey = hkey.unpack('L')[0]
|
306
|
-
|
311
|
+
|
307
312
|
if hash['category_count']
|
308
313
|
data = [hash['category_count']].pack('L')
|
309
|
-
|
314
|
+
|
310
315
|
rv = RegSetValueEx(
|
311
316
|
hkey,
|
312
317
|
'CategoryCount',
|
@@ -315,16 +320,16 @@ module Win32
|
|
315
320
|
data,
|
316
321
|
data.size
|
317
322
|
)
|
318
|
-
|
323
|
+
|
319
324
|
if rv != ERROR_SUCCESS
|
320
325
|
error = 'RegSetValueEx() failed: ' + get_last_error
|
321
326
|
raise Error, error
|
322
327
|
end
|
323
328
|
end
|
324
|
-
|
329
|
+
|
325
330
|
if hash['category_message_file']
|
326
331
|
data = File.expand_path(hash['category_message_file'])
|
327
|
-
|
332
|
+
|
328
333
|
rv = RegSetValueEx(
|
329
334
|
hkey,
|
330
335
|
'CategoryMessageFile',
|
@@ -333,16 +338,16 @@ module Win32
|
|
333
338
|
data,
|
334
339
|
data.size
|
335
340
|
)
|
336
|
-
|
341
|
+
|
337
342
|
if rv != ERROR_SUCCESS
|
338
343
|
error = 'RegSetValueEx() failed: ' + get_last_error
|
339
344
|
raise Error, error
|
340
345
|
end
|
341
346
|
end
|
342
|
-
|
347
|
+
|
343
348
|
if hash['event_message_file']
|
344
349
|
data = File.expand_path(hash['event_message_file'])
|
345
|
-
|
350
|
+
|
346
351
|
rv = RegSetValueEx(
|
347
352
|
hkey,
|
348
353
|
'EventMessageFile',
|
@@ -351,16 +356,16 @@ module Win32
|
|
351
356
|
data,
|
352
357
|
data.size
|
353
358
|
)
|
354
|
-
|
359
|
+
|
355
360
|
if rv != ERROR_SUCCESS
|
356
361
|
error = 'RegSetValueEx() failed: ' + get_last_error
|
357
362
|
raise Error, error
|
358
363
|
end
|
359
364
|
end
|
360
|
-
|
365
|
+
|
361
366
|
if hash['parameter_message_file']
|
362
367
|
data = File.expand_path(hash['parameter_message_file'])
|
363
|
-
|
368
|
+
|
364
369
|
rv = RegSetValueEx(
|
365
370
|
hkey,
|
366
371
|
'ParameterMessageFile',
|
@@ -369,13 +374,13 @@ module Win32
|
|
369
374
|
data,
|
370
375
|
data.size
|
371
376
|
)
|
372
|
-
|
377
|
+
|
373
378
|
if rv != ERROR_SUCCESS
|
374
379
|
error = 'RegSetValueEx() failed: ' + get_last_error
|
375
380
|
raise Error, error
|
376
381
|
end
|
377
|
-
end
|
378
|
-
|
382
|
+
end
|
383
|
+
|
379
384
|
data = [hash['supported_types']].pack('L')
|
380
385
|
|
381
386
|
rv = RegSetValueEx(
|
@@ -386,7 +391,7 @@ module Win32
|
|
386
391
|
data,
|
387
392
|
data.size
|
388
393
|
)
|
389
|
-
|
394
|
+
|
390
395
|
if rv != ERROR_SUCCESS
|
391
396
|
error = 'RegSetValueEx() failed: ' + get_last_error
|
392
397
|
raise Error, error
|
@@ -394,13 +399,13 @@ module Win32
|
|
394
399
|
ensure
|
395
400
|
RegCloseKey(hkey)
|
396
401
|
end
|
397
|
-
|
402
|
+
|
398
403
|
disposition.unpack('L')[0]
|
399
404
|
end
|
400
|
-
|
405
|
+
|
401
406
|
# Backs up the event log to +file+. Note that you cannot backup to
|
402
407
|
# a file that already exists or a Error will be raised.
|
403
|
-
#
|
408
|
+
#
|
404
409
|
def backup(file)
|
405
410
|
raise TypeError unless file.is_a?(String)
|
406
411
|
unless BackupEventLog(@handle, file)
|
@@ -409,99 +414,99 @@ module Win32
|
|
409
414
|
end
|
410
415
|
self
|
411
416
|
end
|
412
|
-
|
417
|
+
|
413
418
|
# Clears the EventLog. If +backup_file+ is provided, it backs up the
|
414
419
|
# event log to that file first.
|
415
|
-
#
|
420
|
+
#
|
416
421
|
def clear(backup_file = nil)
|
417
422
|
raise TypeError unless backup_file.is_a?(String) if backup_file
|
418
423
|
backup_file = 0 unless backup_file
|
419
|
-
|
424
|
+
|
420
425
|
unless ClearEventLog(@handle, backup_file)
|
421
426
|
error = 'ClearEventLog() failed: ' + get_last_error
|
422
427
|
raise Error
|
423
428
|
end
|
424
|
-
|
429
|
+
|
425
430
|
self
|
426
431
|
end
|
427
|
-
|
432
|
+
|
428
433
|
# Closes the EventLog handle. The handle is automatically closed for you
|
429
434
|
# if you use the block form of EventLog.new.
|
430
|
-
#
|
435
|
+
#
|
431
436
|
def close
|
432
437
|
CloseEventLog(@handle)
|
433
438
|
end
|
434
|
-
|
439
|
+
|
435
440
|
# Indicates whether or not the event log is full.
|
436
|
-
#
|
441
|
+
#
|
437
442
|
def full?
|
438
443
|
buf = [0].pack('L') # dwFull
|
439
444
|
needed = [0].pack('L')
|
440
|
-
|
445
|
+
|
441
446
|
unless GetEventLogInformation(@handle, 0, buf, buf.size, needed)
|
442
447
|
raise Error, 'GetEventLogInformation() failed: ' + get_last_error
|
443
448
|
end
|
444
449
|
|
445
450
|
buf[0,4].unpack('L')[0] != 0
|
446
451
|
end
|
447
|
-
|
452
|
+
|
448
453
|
# Returns the absolute record number of the oldest record. Note that
|
449
454
|
# this is not guaranteed to be 1 because event log records can be
|
450
455
|
# overwritten.
|
451
|
-
#
|
456
|
+
#
|
452
457
|
def oldest_record_number
|
453
458
|
rec = [0].pack('L')
|
454
|
-
|
459
|
+
|
455
460
|
unless GetOldestEventLogRecord(@handle, rec)
|
456
461
|
error = 'GetOldestEventLogRecord() failed: ' + get_last_error
|
457
462
|
raise Error, error
|
458
463
|
end
|
459
|
-
|
464
|
+
|
460
465
|
rec.unpack('L')[0]
|
461
466
|
end
|
462
|
-
|
467
|
+
|
463
468
|
# Returns the total number of records for the given event log.
|
464
|
-
#
|
469
|
+
#
|
465
470
|
def total_records
|
466
471
|
total = [0].pack('L')
|
467
|
-
|
472
|
+
|
468
473
|
unless GetNumberOfEventLogRecords(@handle, total)
|
469
474
|
error = 'GetNumberOfEventLogRecords() failed: ' + get_last_error
|
470
475
|
raise Error, error
|
471
476
|
end
|
472
|
-
|
477
|
+
|
473
478
|
total.unpack('L')[0]
|
474
479
|
end
|
475
|
-
|
480
|
+
|
476
481
|
# Yields an EventLogStruct every time a record is written to the event
|
477
482
|
# log. Unlike EventLog#tail, this method breaks out of the block after
|
478
483
|
# the event.
|
479
|
-
#
|
484
|
+
#
|
480
485
|
# Raises an Error if no block is provided.
|
481
|
-
#
|
486
|
+
#
|
482
487
|
def notify_change(&block)
|
483
488
|
unless block_given?
|
484
489
|
raise Error, 'block missing for notify_change()'
|
485
490
|
end
|
486
|
-
|
491
|
+
|
487
492
|
# Reopen the handle because the NotifyChangeEventLog() function will
|
488
493
|
# choke after five or six reads otherwise.
|
489
494
|
@handle = OpenEventLog(@server, @source)
|
490
|
-
|
495
|
+
|
491
496
|
if @handle == 0
|
492
497
|
error = 'OpenEventLog() failed: ' + get_last_error
|
493
498
|
raise Error, error
|
494
499
|
end
|
495
|
-
|
500
|
+
|
496
501
|
event = CreateEvent(0, 0, 0, 0)
|
497
|
-
|
502
|
+
|
498
503
|
unless NotifyChangeEventLog(@handle, event)
|
499
504
|
error = 'NotifyChangeEventLog() failed: ' + get_last_error
|
500
505
|
raise Error, error
|
501
506
|
end
|
502
|
-
|
507
|
+
|
503
508
|
wait_result = WaitForSingleObject(event, INFINITE)
|
504
|
-
|
509
|
+
|
505
510
|
begin
|
506
511
|
if wait_result == WAIT_FAILED
|
507
512
|
error = 'WaitForSingleObject() failed: ' + get_last_error
|
@@ -513,33 +518,33 @@ module Win32
|
|
513
518
|
ensure
|
514
519
|
CloseHandle(event)
|
515
520
|
end
|
516
|
-
|
521
|
+
|
517
522
|
self
|
518
523
|
end
|
519
|
-
|
524
|
+
|
520
525
|
# Yields an EventLogStruct every time a record is written to the event
|
521
526
|
# log, once every +frequency+ seconds. Unlike EventLog#notify_change,
|
522
527
|
# this method does not break out of the block after the event. The read
|
523
528
|
# +frequency+ is set to 5 seconds by default.
|
524
|
-
#
|
529
|
+
#
|
525
530
|
# Raises an Error if no block is provided.
|
526
|
-
#
|
531
|
+
#
|
527
532
|
# The delay between reads is due to the nature of the Windows event log.
|
528
533
|
# It is not really designed to be tailed in the manner of a Unix syslog,
|
529
|
-
# for example, in that not nearly as many events are typically recorded.
|
534
|
+
# for example, in that not nearly as many events are typically recorded.
|
530
535
|
# It's just not designed to be polled that heavily.
|
531
536
|
#
|
532
537
|
def tail(frequency = 5)
|
533
538
|
unless block_given?
|
534
539
|
raise Error, 'block missing for tail()'
|
535
540
|
end
|
536
|
-
|
537
|
-
old_total = total_records()
|
541
|
+
|
542
|
+
old_total = total_records()
|
538
543
|
flags = FORWARDS_READ | SEEK_READ
|
539
544
|
rec_num = read_last_event.record_number
|
540
|
-
|
541
|
-
while true
|
542
|
-
new_total = total_records()
|
545
|
+
|
546
|
+
while true
|
547
|
+
new_total = total_records()
|
543
548
|
if new_total != old_total
|
544
549
|
rec_num = oldest_record_number() if full?
|
545
550
|
read(flags, rec_num).each{ |log| yield log }
|
@@ -549,20 +554,20 @@ module Win32
|
|
549
554
|
sleep frequency
|
550
555
|
end
|
551
556
|
end
|
552
|
-
|
557
|
+
|
553
558
|
# Iterates over each record in the event log, yielding a EventLogStruct
|
554
559
|
# for each record. The offset value is only used when used in
|
555
560
|
# conjunction with the EventLog::SEEK_READ flag. Otherwise, it is
|
556
561
|
# ignored. If no flags are specified, then the default flags are:
|
557
|
-
#
|
562
|
+
#
|
558
563
|
# EventLog::SEQUENTIAL_READ | EventLog::FORWARDS_READ
|
559
564
|
#
|
560
565
|
# Note that, if you're performing a SEEK_READ, then the offset must
|
561
566
|
# refer to a record number that actually exists. The default of 0
|
562
567
|
# may or may not work for your particular event log.
|
563
|
-
#
|
568
|
+
#
|
564
569
|
# The EventLogStruct struct contains the following members:
|
565
|
-
#
|
570
|
+
#
|
566
571
|
# * record_number # Fixnum
|
567
572
|
# * time_generated # Time
|
568
573
|
# * time_written # Time
|
@@ -574,16 +579,16 @@ module Win32
|
|
574
579
|
# * user # String or nil
|
575
580
|
# * description # String or nil
|
576
581
|
# * string_inserts # An array of Strings or nil
|
577
|
-
#
|
582
|
+
#
|
578
583
|
# If no block is given the method returns an array of EventLogStruct's.
|
579
|
-
#
|
584
|
+
#
|
580
585
|
def read(flags = nil, offset = 0)
|
581
|
-
buf = 0.chr * BUFFER_SIZE # 64k buffer
|
586
|
+
buf = 0.chr * BUFFER_SIZE # 64k buffer
|
582
587
|
read = [0].pack('L')
|
583
588
|
needed = [0].pack('L')
|
584
589
|
array = []
|
585
590
|
lkey = HKEY_LOCAL_MACHINE
|
586
|
-
|
591
|
+
|
587
592
|
unless flags
|
588
593
|
flags = FORWARDS_READ | SEQUENTIAL_READ
|
589
594
|
end
|
@@ -595,27 +600,27 @@ module Win32
|
|
595
600
|
end
|
596
601
|
lkey = hkey.unpack('L').first
|
597
602
|
end
|
598
|
-
|
603
|
+
|
599
604
|
while ReadEventLog(@handle, flags, offset, buf, buf.size, read, needed) ||
|
600
605
|
GetLastError() == ERROR_INSUFFICIENT_BUFFER
|
601
|
-
|
606
|
+
|
602
607
|
if GetLastError() == ERROR_INSUFFICIENT_BUFFER
|
603
608
|
buf = (0.chr * buf.size) + (0.chr * needed.unpack('L')[0])
|
604
609
|
unless ReadEventLog(@handle, flags, offset, buf, buf.size, read, needed)
|
605
610
|
raise Error, get_last_error
|
606
611
|
end
|
607
612
|
end
|
608
|
-
|
613
|
+
|
609
614
|
dwread = read.unpack('L')[0]
|
610
|
-
|
615
|
+
|
611
616
|
while dwread > 0
|
612
617
|
struct = EventLogStruct.new
|
613
618
|
event_source = buf[56..-1].nstrip
|
614
619
|
computer = buf[56 + event_source.length + 1..-1].nstrip
|
615
|
-
|
620
|
+
|
616
621
|
user = get_user(buf)
|
617
622
|
strings, desc = get_description(buf, event_source, lkey)
|
618
|
-
|
623
|
+
|
619
624
|
struct.source = event_source
|
620
625
|
struct.computer = computer
|
621
626
|
struct.record_number = buf[8,4].unpack('L')[0]
|
@@ -627,7 +632,7 @@ module Win32
|
|
627
632
|
struct.category = buf[28,2].unpack('S')[0]
|
628
633
|
struct.string_inserts = strings
|
629
634
|
struct.description = desc
|
630
|
-
|
635
|
+
|
631
636
|
struct.freeze # This is read-only information
|
632
637
|
|
633
638
|
if block_given?
|
@@ -635,30 +640,30 @@ module Win32
|
|
635
640
|
else
|
636
641
|
array.push(struct)
|
637
642
|
end
|
638
|
-
|
643
|
+
|
639
644
|
if flags & EVENTLOG_BACKWARDS_READ > 0
|
640
645
|
offset = buf[8,4].unpack('L')[0] - 1
|
641
646
|
else
|
642
647
|
offset = buf[8,4].unpack('L')[0] + 1
|
643
648
|
end
|
644
|
-
|
649
|
+
|
645
650
|
length = buf[0,4].unpack('L')[0] # Length
|
646
651
|
|
647
652
|
dwread -= length
|
648
653
|
buf = buf[length..-1]
|
649
654
|
end
|
650
|
-
|
655
|
+
|
651
656
|
buf = 0.chr * BUFFER_SIZE
|
652
657
|
read = [0].pack('L')
|
653
658
|
end
|
654
|
-
|
659
|
+
|
655
660
|
block_given? ? nil : array
|
656
661
|
end
|
657
|
-
|
662
|
+
|
658
663
|
# This class method is nearly identical to the EventLog#read instance
|
659
664
|
# method, except that it takes a +source+ and +server+ as the first two
|
660
665
|
# arguments.
|
661
|
-
#
|
666
|
+
#
|
662
667
|
def self.read(source='Application', server=nil, flags=nil, offset=0)
|
663
668
|
self.new(source, server){ |log|
|
664
669
|
if block_given?
|
@@ -670,28 +675,28 @@ module Win32
|
|
670
675
|
end
|
671
676
|
|
672
677
|
# Writes an event to the event log. The following are valid keys:
|
673
|
-
#
|
678
|
+
#
|
674
679
|
# * source # Event log source name. Defaults to "Application"
|
675
680
|
# * event_id # Event ID (defined in event message file)
|
676
681
|
# * category # Event category (defined in category message file)
|
677
682
|
# * data # String that is written to the log
|
678
683
|
# * event_type # Type of event, e.g. EventLog::ERROR, etc.
|
679
|
-
#
|
684
|
+
#
|
680
685
|
# The +event_type+ keyword is the only mandatory keyword. The others are
|
681
686
|
# optional. Although the +source+ defaults to "Application", I
|
682
687
|
# recommend that you create an application specific event source and use
|
683
688
|
# that instead. See the 'EventLog.add_event_source' method for more
|
684
689
|
# details.
|
685
|
-
#
|
690
|
+
#
|
686
691
|
# The +event_id+ and +category+ values are defined in the message
|
687
692
|
# file(s) that you created for your application. See the tutorial.txt
|
688
693
|
# file for more details on how to create a message file.
|
689
|
-
#
|
694
|
+
#
|
690
695
|
# An ArgumentError is raised if you attempt to use an invalid key.
|
691
|
-
#
|
696
|
+
#
|
692
697
|
def report_event(args)
|
693
698
|
raise TypeError unless args.is_a?(Hash)
|
694
|
-
|
699
|
+
|
695
700
|
valid_keys = %w/source event_id category data event_type/
|
696
701
|
num_strings = 0
|
697
702
|
|
@@ -702,8 +707,8 @@ module Win32
|
|
702
707
|
'category' => 0,
|
703
708
|
'data' => 0
|
704
709
|
}
|
705
|
-
|
706
|
-
# Validate the keys, and convert symbols and case to lowercase strings.
|
710
|
+
|
711
|
+
# Validate the keys, and convert symbols and case to lowercase strings.
|
707
712
|
args.each{ |key, val|
|
708
713
|
key = key.to_s.downcase
|
709
714
|
unless valid_keys.include?(key)
|
@@ -711,19 +716,19 @@ module Win32
|
|
711
716
|
end
|
712
717
|
hash[key] = val
|
713
718
|
}
|
714
|
-
|
719
|
+
|
715
720
|
# The event_type must be specified
|
716
721
|
unless hash['event_type']
|
717
722
|
raise Error, 'no event_type specified'
|
718
723
|
end
|
719
|
-
|
724
|
+
|
720
725
|
handle = RegisterEventSource(@server, hash['source'])
|
721
|
-
|
726
|
+
|
722
727
|
if handle == 0
|
723
728
|
error = 'RegisterEventSource() failed: ' + get_last_error
|
724
729
|
raise Error, error
|
725
730
|
end
|
726
|
-
|
731
|
+
|
727
732
|
if hash['data'].is_a?(String)
|
728
733
|
data = hash['data'] << 0.chr
|
729
734
|
data = [data].pack('p*')
|
@@ -732,7 +737,7 @@ module Win32
|
|
732
737
|
data = 0
|
733
738
|
num_strings = 0
|
734
739
|
end
|
735
|
-
|
740
|
+
|
736
741
|
bool = ReportEvent(
|
737
742
|
handle,
|
738
743
|
hash['event_type'],
|
@@ -744,29 +749,29 @@ module Win32
|
|
744
749
|
data,
|
745
750
|
0
|
746
751
|
)
|
747
|
-
|
752
|
+
|
748
753
|
unless bool
|
749
754
|
error = 'ReportEvent() failed: ' + get_last_error
|
750
755
|
raise Error, error
|
751
756
|
end
|
752
|
-
|
757
|
+
|
753
758
|
self
|
754
759
|
end
|
755
|
-
|
760
|
+
|
756
761
|
alias :write :report_event
|
757
|
-
|
762
|
+
|
758
763
|
private
|
759
|
-
|
764
|
+
|
760
765
|
# A private method that reads the last event log record.
|
761
|
-
#
|
766
|
+
#
|
762
767
|
def read_last_event(handle=@handle, source=@source, server=@server)
|
763
768
|
buf = 0.chr * BUFFER_SIZE # 64k buffer
|
764
769
|
read = [0].pack('L')
|
765
770
|
needed = [0].pack('L')
|
766
771
|
lkey = HKEY_LOCAL_MACHINE
|
767
|
-
|
772
|
+
|
768
773
|
flags = EVENTLOG_BACKWARDS_READ | EVENTLOG_SEQUENTIAL_READ
|
769
|
-
|
774
|
+
|
770
775
|
unless ReadEventLog(@handle, flags, 0, buf, buf.size, read, needed)
|
771
776
|
error = GetLastError()
|
772
777
|
if error == ERROR_INSUFFICIENT_BUFFER
|
@@ -786,13 +791,13 @@ module Win32
|
|
786
791
|
end
|
787
792
|
lkey = hkey.unpack('L').first
|
788
793
|
end
|
789
|
-
|
794
|
+
|
790
795
|
event_source = buf[56..-1].nstrip
|
791
796
|
computer = buf[56 + event_source.length + 1..-1].nstrip
|
792
797
|
event_type = get_event_type(buf[24,2].unpack('S')[0])
|
793
798
|
user = get_user(buf)
|
794
799
|
strings, desc = get_description(buf, event_source, lkey)
|
795
|
-
|
800
|
+
|
796
801
|
struct = EventLogStruct.new
|
797
802
|
struct.source = event_source
|
798
803
|
struct.computer = computer
|
@@ -805,16 +810,16 @@ module Win32
|
|
805
810
|
struct.category = buf[28,2].unpack('S')[0]
|
806
811
|
struct.string_inserts = strings
|
807
812
|
struct.description = desc
|
808
|
-
|
813
|
+
|
809
814
|
struct.freeze # This is read-only information
|
810
|
-
|
815
|
+
|
811
816
|
struct
|
812
817
|
end
|
813
|
-
|
818
|
+
|
814
819
|
# Private method that retrieves the user name based on data in the
|
815
820
|
# EVENTLOGRECORD buffer.
|
816
|
-
#
|
817
|
-
def get_user(buf)
|
821
|
+
#
|
822
|
+
def get_user(buf)
|
818
823
|
return nil if buf[40,4].unpack('L')[0] <= 0 # UserSidLength
|
819
824
|
|
820
825
|
name = 0.chr * MAX_SIZE
|
@@ -822,9 +827,9 @@ module Win32
|
|
822
827
|
domain = 0.chr * MAX_SIZE
|
823
828
|
domain_size = [domain.size].pack('L')
|
824
829
|
snu = 0.chr * 4
|
825
|
-
|
830
|
+
|
826
831
|
offset = buf[44,4].unpack('L')[0] # UserSidOffset
|
827
|
-
|
832
|
+
|
828
833
|
val = LookupAccountSid(
|
829
834
|
@server,
|
830
835
|
[buf].pack('P').unpack('L')[0] + offset,
|
@@ -834,14 +839,14 @@ module Win32
|
|
834
839
|
domain_size,
|
835
840
|
snu
|
836
841
|
)
|
837
|
-
|
842
|
+
|
838
843
|
# Return nil if the lookup failed
|
839
844
|
return val ? name.nstrip : nil
|
840
845
|
end
|
841
|
-
|
846
|
+
|
842
847
|
# Private method that converts a numeric event type into a human
|
843
848
|
# readable string.
|
844
|
-
#
|
849
|
+
#
|
845
850
|
def get_event_type(event)
|
846
851
|
case event
|
847
852
|
when EVENTLOG_ERROR_TYPE
|
@@ -858,11 +863,11 @@ module Win32
|
|
858
863
|
nil
|
859
864
|
end
|
860
865
|
end
|
861
|
-
|
866
|
+
|
862
867
|
# Private method that gets the string inserts (Array) and the full
|
863
868
|
# event description (String) based on data from the EVENTLOGRECORD
|
864
869
|
# buffer.
|
865
|
-
#
|
870
|
+
#
|
866
871
|
def get_description(rec, event_source, lkey)
|
867
872
|
str = rec[rec[36,4].unpack('L')[0] .. -1]
|
868
873
|
num = rec[26,2].unpack('S')[0] # NumStrings
|
@@ -892,7 +897,7 @@ module Win32
|
|
892
897
|
hkey2 = [0].pack('L')
|
893
898
|
key = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
|
894
899
|
key << "WINEVT\\Publishers\\#{guid}"
|
895
|
-
|
900
|
+
|
896
901
|
if RegOpenKeyEx(lkey, key, 0, KEY_READ|0x100, hkey2) == 0
|
897
902
|
hkey2 = hkey2.unpack('L')[0]
|
898
903
|
value = 'ParameterMessageFile'
|
@@ -905,7 +910,7 @@ module Win32
|
|
905
910
|
ExpandEnvironmentStrings(file, exe, exe.size)
|
906
911
|
param_exe = exe.nstrip
|
907
912
|
end
|
908
|
-
|
913
|
+
|
909
914
|
value = 'MessageFileName'
|
910
915
|
file = 0.chr * MAX_SIZE
|
911
916
|
size = [file.length].pack('L')
|
@@ -916,7 +921,7 @@ module Win32
|
|
916
921
|
ExpandEnvironmentStrings(file, exe, exe.size)
|
917
922
|
message_exe = exe.nstrip
|
918
923
|
end
|
919
|
-
|
924
|
+
|
920
925
|
RegCloseKey(hkey2)
|
921
926
|
end
|
922
927
|
else
|
@@ -940,9 +945,9 @@ module Win32
|
|
940
945
|
exe = 0.chr * MAX_SIZE
|
941
946
|
ExpandEnvironmentStrings(file, exe, exe.size)
|
942
947
|
message_exe = exe.nstrip
|
943
|
-
|
944
|
-
|
945
|
-
|
948
|
+
end
|
949
|
+
end
|
950
|
+
|
946
951
|
RegCloseKey(hkey)
|
947
952
|
elsif defined? EvtOpenPublisherMetadata # Vista or later
|
948
953
|
pubMetadata = EvtOpenPublisherMetadata(
|
@@ -952,11 +957,11 @@ module Win32
|
|
952
957
|
1024, # Default LCID
|
953
958
|
0
|
954
959
|
)
|
955
|
-
|
960
|
+
|
956
961
|
if pubMetadata > 0
|
957
962
|
buf2 = 0.chr * 8192
|
958
963
|
val = 0.chr*4
|
959
|
-
|
964
|
+
|
960
965
|
EvtGetPublisherMetadataProperty(
|
961
966
|
pubMetadata,
|
962
967
|
2, # EvtPublisherMetadataParameterFilePath
|
@@ -965,7 +970,7 @@ module Win32
|
|
965
970
|
buf2,
|
966
971
|
val
|
967
972
|
)
|
968
|
-
|
973
|
+
|
969
974
|
file = wide_to_multi(buf2[16..-1])
|
970
975
|
exe = 0.chr * MAX_SIZE
|
971
976
|
ExpandEnvironmentStrings(file, exe, exe.size)
|
@@ -973,7 +978,7 @@ module Win32
|
|
973
978
|
|
974
979
|
buf2 = 0.chr * 8192
|
975
980
|
val = 0.chr*4
|
976
|
-
|
981
|
+
|
977
982
|
EvtGetPublisherMetadataProperty(
|
978
983
|
pubMetadata,
|
979
984
|
3, # EvtPublisherMetadataMessageFilePath
|
@@ -982,7 +987,7 @@ module Win32
|
|
982
987
|
buf2,
|
983
988
|
val
|
984
989
|
)
|
985
|
-
|
990
|
+
|
986
991
|
file = wide_to_multi(buf2[16..-1])
|
987
992
|
exe = 0.chr * MAX_SIZE
|
988
993
|
ExpandEnvironmentStrings(file, exe, exe.size)
|
@@ -1015,7 +1020,7 @@ module Win32
|
|
1015
1020
|
buf.size,
|
1016
1021
|
v
|
1017
1022
|
)
|
1018
|
-
|
1023
|
+
|
1019
1024
|
if res == 0
|
1020
1025
|
event_id = 0xB0000000 | event_id
|
1021
1026
|
res = FormatMessage(
|
@@ -1052,7 +1057,7 @@ module Win32
|
|
1052
1057
|
)
|
1053
1058
|
|
1054
1059
|
event_id = rec[20,4].unpack('L')[0]
|
1055
|
-
|
1060
|
+
|
1056
1061
|
if hmodule != 0
|
1057
1062
|
res = FormatMessage(
|
1058
1063
|
FORMAT_MESSAGE_FROM_HMODULE |
|
@@ -1064,10 +1069,10 @@ module Win32
|
|
1064
1069
|
buf.size,
|
1065
1070
|
nil
|
1066
1071
|
)
|
1067
|
-
|
1072
|
+
|
1068
1073
|
if res == 0
|
1069
1074
|
event_id = 0xB0000000 | event_id
|
1070
|
-
|
1075
|
+
|
1071
1076
|
res = FormatMessage(
|
1072
1077
|
FORMAT_MESSAGE_FROM_HMODULE |
|
1073
1078
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
@@ -1079,7 +1084,7 @@ module Win32
|
|
1079
1084
|
nil
|
1080
1085
|
)
|
1081
1086
|
end
|
1082
|
-
|
1087
|
+
|
1083
1088
|
FreeLibrary(hmodule)
|
1084
1089
|
break if buf.nstrip != "" # All messages read
|
1085
1090
|
end
|
@@ -1098,7 +1103,7 @@ module Win32
|
|
1098
1103
|
[x + 0.chr].pack('P').unpack('L')[0]
|
1099
1104
|
}.pack('L*')
|
1100
1105
|
end
|
1101
|
-
|
1106
|
+
|
1102
1107
|
message_exe.split(';').each{ |file|
|
1103
1108
|
hmodule = LoadLibraryEx(
|
1104
1109
|
file,
|
@@ -1119,10 +1124,10 @@ module Win32
|
|
1119
1124
|
buf.size,
|
1120
1125
|
va_list_ptr
|
1121
1126
|
)
|
1122
|
-
|
1127
|
+
|
1123
1128
|
if res == 0
|
1124
1129
|
event_id = 0xB0000000 | event_id
|
1125
|
-
|
1130
|
+
|
1126
1131
|
res = FormatMessage(
|
1127
1132
|
FORMAT_MESSAGE_FROM_HMODULE |
|
1128
1133
|
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
@@ -1147,6 +1152,6 @@ module Win32
|
|
1147
1152
|
end
|
1148
1153
|
|
1149
1154
|
[va_list0, buf.nstrip]
|
1150
|
-
end
|
1155
|
+
end
|
1151
1156
|
end
|
1152
1157
|
end
|