win32-eventlog 0.5.2 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|