win32-eventlog 0.5.0 → 0.5.1
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 +23 -12
- data/MANIFEST +3 -3
- data/README +19 -14
- data/Rakefile +27 -3
- data/doc/tutorial.txt +5 -5
- data/examples/example_notify.rb +24 -0
- data/examples/example_read.rb +84 -0
- data/examples/example_write.rb +65 -0
- data/lib/win32/eventlog.rb +53 -20
- data/lib/win32/mc.rb +21 -8
- data/misc/install_msg.rb +48 -0
- data/misc/rubymsg.mc +35 -0
- data/test/test_eventlog.rb +22 -12
- data/test/test_mc.rb +15 -15
- data/win32-eventlog.gemspec +28 -22
- metadata +20 -19
- data/win32-eventlog-0.5.0.gem +0 -0
data/CHANGES
CHANGED
@@ -1,4 +1,15 @@
|
|
1
|
-
|
1
|
+
== 0.5.1 - 8-Aug-2009
|
2
|
+
* License changed to Artistic 2.0.
|
3
|
+
* Some gemspec updates; test-unit and ptools are now development dependencies
|
4
|
+
instead of runtime dependencies and the description has been updated.
|
5
|
+
* Some RDoc updates, including documentation of the event type constants.
|
6
|
+
* Several RDoc updates for the Win32::MC class.
|
7
|
+
* Minor refactoring of the test suite.
|
8
|
+
* Added rake tasks for running the mc or eventlog libraries separately, as
|
9
|
+
well as tasks for running the examples.
|
10
|
+
* Example programs renamed to avoid any confusion with actual test files.
|
11
|
+
|
12
|
+
== 0.5.0 - 12-Sep-2008
|
2
13
|
* Fixed an issue for Windows Vista and later where some event descriptions
|
3
14
|
were missing. This fix requires windows-pr 0.9.3 or later.
|
4
15
|
* The EventLog#full? method now raises an EventLog::Error if it should fail
|
@@ -9,7 +20,7 @@
|
|
9
20
|
* Renamed the test files to start with 'test_'.
|
10
21
|
* Removed the ts_all.rb file.
|
11
22
|
|
12
|
-
|
23
|
+
== 0.4.9 - 7-Sep-2008
|
13
24
|
* The private get_description method, which is used internally to read the
|
14
25
|
event log, has been updated to work with 64 bit Windows. The changes needed
|
15
26
|
for this require a more recent windows-pr library, i.e. 0.9.2 or later.
|
@@ -18,14 +29,14 @@
|
|
18
29
|
properties for both the EventLog#tail and EventLog#notify_change methods.
|
19
30
|
* Some internal refactoring to use begin/ensure where appropriate.
|
20
31
|
|
21
|
-
|
32
|
+
== 0.4.8 - 17-May-2008
|
22
33
|
* Fixed in a bug in the EventLog#read method where a log entry requiring
|
23
34
|
over 64k would fail and spiral into an infinite loop. Thanks go to
|
24
35
|
Stuart Clarke for the spot.
|
25
36
|
* Improved handling of failed log reading in the read_last_event private
|
26
37
|
method.
|
27
38
|
|
28
|
-
|
39
|
+
== 0.4.7 - 8-Dec-2007
|
29
40
|
* Fixed a bug where you couldn't write to custom (parent) event sources.
|
30
41
|
Thanks go to Tim Uckun for the spot.
|
31
42
|
* Now handles ParameterMessageFiles, both in the EventLog.add_event_source
|
@@ -36,20 +47,20 @@
|
|
36
47
|
* The EventLog.add_event_source now returns the creation disposition
|
37
48
|
instead of self.
|
38
49
|
|
39
|
-
|
50
|
+
== 0.4.6 - 27-Aug-2007
|
40
51
|
* Reading event logs is now approximately 5-7 times faster!
|
41
52
|
* Fixed a potential bug where, in rare cases, event descriptions could be
|
42
53
|
overwritten by other event descriptions.
|
43
54
|
* Fixed a bug where, in unusual cases, there was leading garbage in the
|
44
55
|
event descriptions.
|
45
56
|
|
46
|
-
|
57
|
+
== 0.4.5 - 25-Aug-2007
|
47
58
|
* Fixed two potential issues where reading from remote event log sources
|
48
59
|
could fail either due to permissions (reading DLL's) or because local
|
49
60
|
registry entries didn't necessarily match the remote registry entries.
|
50
61
|
Thanks go to Andrew Garberoglio and Ivan Shiel for the spot.
|
51
62
|
|
52
|
-
|
63
|
+
== 0.4.4 - 31-Jul-2007
|
53
64
|
* The EventLogError class is now EventLog::Error.
|
54
65
|
* The MCError class is now MC::Error.
|
55
66
|
* Added a Rakefile with tasks for installation and testing.
|
@@ -58,14 +69,14 @@
|
|
58
69
|
* Added some more source comments.
|
59
70
|
* Updates to the README and MANIFEST file.
|
60
71
|
|
61
|
-
|
72
|
+
== 0.4.3 - 18-Dec-2006
|
62
73
|
* Removed the FORMAT_MESSAGE_FROM_SYSTEM flag to the FormatMessage function
|
63
74
|
in the get_description private method because it could sometimes return
|
64
75
|
bogus information. Thanks go to Greg Holmes for the spot.
|
65
76
|
* Added the string_inserts member to the EventLogStruct. This contains an
|
66
77
|
array of only the raw string inserts, rather than the entire text message.
|
67
78
|
|
68
|
-
|
79
|
+
== 0.4.2 - 6-Aug-2006
|
69
80
|
* Fixed a bug in the EventLog.read method related to the
|
70
81
|
EVENTLOG_BACKWARDS_READ flag.
|
71
82
|
* Fixed a bug in the EventLog.read method where the event_type was not being
|
@@ -73,11 +84,11 @@
|
|
73
84
|
* Fixed bugs in the EventLog#tail method where it would fail if the log was
|
74
85
|
full and dups would appear.
|
75
86
|
|
76
|
-
|
87
|
+
== 0.4.1 - 28-May-2006
|
77
88
|
* Fixed a bug in the EventLog#notify_change method where the handle would
|
78
89
|
die after five or six reads. Thanks go to botp for the spot.
|
79
90
|
|
80
|
-
|
91
|
+
== 0.4.0 - 24-May-2006
|
81
92
|
* Now pure Ruby.
|
82
93
|
* Now includes a gemspec.
|
83
94
|
* Fixed a major bug the EventLog#tail method where it was reading the log in
|
@@ -100,7 +111,7 @@
|
|
100
111
|
* Made the .txt files rdoc friendly, and removed the .rd files.
|
101
112
|
* Minor adjustments to the test suite.
|
102
113
|
|
103
|
-
|
114
|
+
=== 0.3.1 - 16-Feb-2005
|
104
115
|
* Minor modifications to the source to eliminate some warnings that appeared
|
105
116
|
in Ruby 1.8.2 or later, plus other minor tweaks.
|
106
117
|
* Renamed the sample programs and moved the 'examples' directory to the
|
data/MANIFEST
CHANGED
@@ -4,9 +4,9 @@
|
|
4
4
|
* Rakefile
|
5
5
|
* win32-eventlog.gemspec
|
6
6
|
* doc/tutorial.txt
|
7
|
-
* examples/
|
8
|
-
* examples/
|
9
|
-
* examples/
|
7
|
+
* examples/example_read.rb
|
8
|
+
* examples/example_write.rb
|
9
|
+
* examples/example_notify.rb
|
10
10
|
* lib/win32/eventlog.rb
|
11
11
|
* lib/win32/mc.rb
|
12
12
|
* misc/install_msg.rb
|
data/README
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
== Description
|
2
2
|
The win32-eventlog library provides an interface for reading from and
|
3
3
|
writing to the MS Windows Event Log.
|
4
4
|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
win32-mc library (provided with this distro), assuming you have the
|
7
7
|
proper tools installed.
|
8
8
|
|
9
|
-
|
9
|
+
== Prerequisites
|
10
10
|
Ruby 1.8.2 or later.
|
11
11
|
windows-pr 0.9.3 or later.
|
12
12
|
|
@@ -14,15 +14,19 @@
|
|
14
14
|
install message sources. You won't need these for simply reading from or
|
15
15
|
writing to an existing event log.
|
16
16
|
|
17
|
-
|
17
|
+
== Installation
|
18
|
+
=== Gem Installation
|
19
|
+
gem install win32-eventlog
|
20
|
+
=== Local Installation
|
18
21
|
rake test (optional)
|
19
22
|
rake install (non-gem) or rake install_gem (gem)
|
20
23
|
|
24
|
+
=== General Installation Notes
|
21
25
|
This will install both the win32-eventlog and win32-mc libraries. The latter
|
22
26
|
is strictly for turning .mc files into .dll files. See the mc documentation
|
23
27
|
for more details.
|
24
28
|
|
25
|
-
|
29
|
+
== Installing the 'RubyMsg' event source
|
26
30
|
If you wish to install the RubyMsg event source, run the 'install_msg.rb'
|
27
31
|
script in the 'misc' directory. This will create a 'rubymsg' directory
|
28
32
|
under your toplevel Ruby installation directory (usually C:\ruby), and
|
@@ -37,32 +41,33 @@
|
|
37
41
|
you do not understand this, please read the 'tutorial.txt' file in the 'doc'
|
38
42
|
directory.
|
39
43
|
|
40
|
-
|
44
|
+
== Additional documentation
|
41
45
|
If you are unfamiliar with message files and event logging on Windows in
|
42
46
|
general, please read the 'tutorial.txt' file.
|
43
47
|
|
44
48
|
There are also a couple of sample test scripts under the 'examples'
|
45
49
|
directory if you want to futz around and get a feel for how things work.
|
46
50
|
|
47
|
-
|
48
|
-
|
49
|
-
installed or they're not in your
|
50
|
-
them somewhere on your
|
51
|
+
== If the test_mc.rb tests are skipped
|
52
|
+
If the tests from the test_mc.rb file are omitted then you either don't
|
53
|
+
have the mc, rc and/or link commands installed or they're not in your
|
54
|
+
system's %PATH%. If you have MSVC++, you should have them somewhere on your
|
55
|
+
system.
|
51
56
|
|
52
|
-
|
57
|
+
== Known Issues
|
53
58
|
None known.
|
54
59
|
|
55
60
|
Please file any bug reports on the project page at
|
56
61
|
http://www.rubyforge.org/projects/win32utils.
|
57
62
|
|
58
|
-
|
59
|
-
|
63
|
+
== License
|
64
|
+
Artistic 2.0
|
60
65
|
|
61
|
-
|
66
|
+
== Warranty
|
62
67
|
This package is provided "as is" and without any express or
|
63
68
|
implied warranties, including, without limitation, the implied
|
64
69
|
warranties of merchantability and fitness for a particular purpose.
|
65
70
|
|
66
|
-
|
71
|
+
== Authors
|
67
72
|
Daniel J. Berger
|
68
73
|
Park Heesob
|
data/Rakefile
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/testtask'
|
3
3
|
|
4
|
-
desc
|
4
|
+
desc 'Install win32-eventlog and win32-mc (non-gem)'
|
5
5
|
task :install do
|
6
6
|
dest = File.join(Config::CONFIG['sitelibdir'], 'win32')
|
7
7
|
Dir.mkdir(dest) unless File.exists? dest
|
@@ -9,14 +9,38 @@ task :install do
|
|
9
9
|
cp 'lib/win32/mc.rb', dest, :verbose => true
|
10
10
|
end
|
11
11
|
|
12
|
-
desc
|
12
|
+
desc 'Install the win32-eventlog library as a gem'
|
13
13
|
task :install_gem do
|
14
14
|
ruby 'win32-eventlog.gemspec'
|
15
15
|
file = Dir["*.gem"].first
|
16
16
|
sh "gem install #{file}"
|
17
17
|
end
|
18
18
|
|
19
|
-
|
19
|
+
desc 'Run the notify (tail) example program'
|
20
|
+
task :example_notify do
|
21
|
+
ruby '-Ilib examples/example_notify.rb'
|
22
|
+
|
23
|
+
desc 'Run the read example program'
|
24
|
+
task :example_read do
|
25
|
+
ruby '-Ilib examples/example_read.rb'
|
26
|
+
|
27
|
+
desc 'Run the write example program'
|
28
|
+
task :example_write do
|
29
|
+
ruby '-Ilib examples/example_write.rb'
|
30
|
+
|
31
|
+
Rake::TestTask.new(:test) do |t|
|
20
32
|
t.warning = true
|
21
33
|
t.verbose = true
|
22
34
|
end
|
35
|
+
|
36
|
+
Rake::TestTask.new(:test_eventlog) do |t|
|
37
|
+
t.warning = true
|
38
|
+
t.verbose = true
|
39
|
+
t.test_files = Dir['test/test_eventlog.rb']
|
40
|
+
end
|
41
|
+
|
42
|
+
Rake::TestTask.new(:test_mc) do |t|
|
43
|
+
t.warning = true
|
44
|
+
t.verbose = true
|
45
|
+
t.test_files = Dir['test/test_mc.rb']
|
46
|
+
end
|
data/doc/tutorial.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
== Information about Message Files
|
2
2
|
Each event source should register message files that contain description
|
3
3
|
strings for each event identifier, event category, and parameter. Register
|
4
4
|
these files in the EventMessageFile, CategoryMessageFile, and
|
@@ -11,7 +11,7 @@ files. Several applications can share the same message file.
|
|
11
11
|
You should typically create message files as resource-only DLLs. They are
|
12
12
|
smaller and faster than ordinary DLLs.
|
13
13
|
|
14
|
-
|
14
|
+
== What does a .mc file look like?
|
15
15
|
|
16
16
|
A .mc file is just a plain text file that is parsed by the "mc" utility to
|
17
17
|
generate a header and, ultimately, a .dll file. Here is a quick sample.
|
@@ -38,7 +38,7 @@ Language=English
|
|
38
38
|
Error: %1
|
39
39
|
.
|
40
40
|
|
41
|
-
|
41
|
+
== How to generate a .dll file from a .mc file
|
42
42
|
To turn this file into a .dll you have two options. The first is to use the
|
43
43
|
command line utilities. Follow these steps:
|
44
44
|
|
@@ -75,7 +75,7 @@ is the text that shows up in the event description.
|
|
75
75
|
The "data" field is what replaces "%1" as an actual text string in the event
|
76
76
|
log, sort of like a printf format specifier, except that it's always a string.
|
77
77
|
|
78
|
-
|
78
|
+
== Registering an event source
|
79
79
|
First, create the .dll file from the .mc file. Then register that .dll file
|
80
80
|
for an event source we'll call "foo". You can name the .dll file anything
|
81
81
|
you like, but for sanity's sake I recommend keeping the same as the event
|
@@ -99,7 +99,7 @@ been inserted into the registry. You can find it under:
|
|
99
99
|
|
100
100
|
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application.
|
101
101
|
|
102
|
-
|
102
|
+
== Writing to the event source
|
103
103
|
Now that our event source 'foo' is registered, we can begin writing event
|
104
104
|
log data for it. Here's an example of how you use it:
|
105
105
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
############################################################################
|
2
|
+
# example_notify.rb (win32-eventlog)
|
3
|
+
#
|
4
|
+
# A sample script for demonstrating the tail method. Start this in its own
|
5
|
+
# terminal. Then, in another terminal, write an entry to the event log
|
6
|
+
# (or force an entry via some other means) and watch the output.
|
7
|
+
#
|
8
|
+
# You can run this code via the 'example_notify' rake task.
|
9
|
+
############################################################################
|
10
|
+
Thread.new { loop { sleep 0.01 } } # Allow Ctrl-C
|
11
|
+
|
12
|
+
require 'win32/eventlog'
|
13
|
+
include Win32
|
14
|
+
|
15
|
+
log = EventLog.open
|
16
|
+
|
17
|
+
# replace 'tail' with 'notify_change' to see the difference
|
18
|
+
log.tail{ |struct|
|
19
|
+
puts "Got something"
|
20
|
+
p struct
|
21
|
+
puts
|
22
|
+
}
|
23
|
+
|
24
|
+
log.close
|
@@ -0,0 +1,84 @@
|
|
1
|
+
############################################################################
|
2
|
+
# example_read.rb (win32-eventlog)
|
3
|
+
#
|
4
|
+
# Test script for general futzing. This will attempt to read and backup
|
5
|
+
# your Event Log. You can run this example via the 'rake example_read'
|
6
|
+
# task.
|
7
|
+
#
|
8
|
+
# Modify as you see fit.
|
9
|
+
############################################################################
|
10
|
+
require 'win32/eventlog'
|
11
|
+
include Win32
|
12
|
+
|
13
|
+
puts "VERSION: " + EventLog::VERSION
|
14
|
+
sleep 1
|
15
|
+
|
16
|
+
# A few different ways to read an event log
|
17
|
+
|
18
|
+
el = EventLog.new("Application")
|
19
|
+
el.read{ |log|
|
20
|
+
p log
|
21
|
+
}
|
22
|
+
el.close
|
23
|
+
|
24
|
+
EventLog.read("Application"){ |log|
|
25
|
+
p log
|
26
|
+
puts
|
27
|
+
}
|
28
|
+
|
29
|
+
EventLog.open("Application") do |log|
|
30
|
+
log.read{ |struct|
|
31
|
+
p struct
|
32
|
+
puts
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
backup_file = "C:\\event_backup1"
|
37
|
+
File.delete(backup_file) if File.exists?(backup_file)
|
38
|
+
|
39
|
+
e1 = EventLog.open("System")
|
40
|
+
puts "System log opened"
|
41
|
+
|
42
|
+
e2 = EventLog.open("Application")
|
43
|
+
puts "Application log opened"
|
44
|
+
|
45
|
+
e3 = EventLog.open("Security")
|
46
|
+
puts "Security log opened"
|
47
|
+
|
48
|
+
puts "=" * 40
|
49
|
+
|
50
|
+
puts "Total system records: " + e1.total_records.to_s
|
51
|
+
puts "Total application records: " + e2.total_records.to_s
|
52
|
+
puts "Total security records: " + e3.total_records.to_s
|
53
|
+
|
54
|
+
puts "=" * 40
|
55
|
+
|
56
|
+
puts "Oldest system record number: " + e1.oldest_record_number.to_s
|
57
|
+
puts "Oldest application record number: " + e2.oldest_record_number.to_s
|
58
|
+
puts "Oldest security record number: " + e3.oldest_record_number.to_s
|
59
|
+
|
60
|
+
puts "=" * 40
|
61
|
+
|
62
|
+
e2.backup(backup_file)
|
63
|
+
puts "Application log backed up to #{backup_file}"
|
64
|
+
|
65
|
+
puts "=" * 40
|
66
|
+
|
67
|
+
e1.close
|
68
|
+
puts "System log closed"
|
69
|
+
|
70
|
+
e2.close
|
71
|
+
puts "Application log closed"
|
72
|
+
|
73
|
+
e3.close
|
74
|
+
puts "Security log closed"
|
75
|
+
|
76
|
+
e4 = EventLog.open_backup(backup_file)
|
77
|
+
e4.read{ |elr|
|
78
|
+
p elr
|
79
|
+
puts
|
80
|
+
}
|
81
|
+
puts "Finished reading backup file"
|
82
|
+
e4.close
|
83
|
+
|
84
|
+
File.delete(backup_file)
|
@@ -0,0 +1,65 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# example_write.rb
|
3
|
+
#
|
4
|
+
# Tests both the creation of an Event Log source and writing to the Event
|
5
|
+
# Log. You can run this via the 'rake example_write' task.
|
6
|
+
#
|
7
|
+
# Modify as you see fit.
|
8
|
+
##############################################################################
|
9
|
+
|
10
|
+
# Prompt user to continue, or not...
|
11
|
+
msg = <<TEXT
|
12
|
+
|
13
|
+
This script will create an event source 'foo' in your registry and
|
14
|
+
write an event to the 'Application' source.
|
15
|
+
Is that ok [y/N]?
|
16
|
+
TEXT
|
17
|
+
print msg
|
18
|
+
|
19
|
+
ans = STDIN.gets.chomp
|
20
|
+
unless ans == "y" || ans == "Y"
|
21
|
+
puts "Ok, exiting..."
|
22
|
+
exit!
|
23
|
+
end
|
24
|
+
|
25
|
+
require "win32/eventlog"
|
26
|
+
require "win32/mc"
|
27
|
+
include Win32
|
28
|
+
|
29
|
+
puts "EventLog VERSION: " + EventLog::VERSION
|
30
|
+
puts "MC VERSION: " + MC::VERSION
|
31
|
+
sleep 1
|
32
|
+
|
33
|
+
m = MC.new("foo.mc")
|
34
|
+
m.create_all
|
35
|
+
puts ".dll created"
|
36
|
+
sleep 1
|
37
|
+
|
38
|
+
dll_file = File.expand_path(m.dll_file)
|
39
|
+
|
40
|
+
EventLog.add_event_source(
|
41
|
+
'source' => "Application",
|
42
|
+
'key_name' => "foo",
|
43
|
+
'category_count' => 2,
|
44
|
+
'event_message_file' => dll_file,
|
45
|
+
'category_message_file' => dll_file
|
46
|
+
)
|
47
|
+
|
48
|
+
puts "Event source added to registry"
|
49
|
+
sleep 1
|
50
|
+
|
51
|
+
e1 = EventLog.open("Application")
|
52
|
+
|
53
|
+
e1.report_event(
|
54
|
+
:source => "foo",
|
55
|
+
:event_type => EventLog::WARN,
|
56
|
+
:category => "0x00000002L".hex,
|
57
|
+
:event_id => "0xC0000003L".hex,
|
58
|
+
:data => "Danger Will Robinson!"
|
59
|
+
)
|
60
|
+
|
61
|
+
puts "Event written to event log"
|
62
|
+
|
63
|
+
e1.close
|
64
|
+
|
65
|
+
puts "Finished. Exiting..."
|
data/lib/win32/eventlog.rb
CHANGED
@@ -38,27 +38,61 @@ module Win32
|
|
38
38
|
extend Windows::Registry
|
39
39
|
|
40
40
|
# The version of the win32-eventlog library
|
41
|
-
VERSION = '0.5.
|
41
|
+
VERSION = '0.5.1'
|
42
42
|
|
43
|
-
#
|
44
|
-
FORWARDS_READ
|
43
|
+
# The log is read in chronological order, i.e. oldest to newest.
|
44
|
+
FORWARDS_READ = EVENTLOG_FORWARDS_READ
|
45
|
+
|
46
|
+
# The log is read in reverse chronological order, i.e. newest to oldest.
|
45
47
|
BACKWARDS_READ = EVENTLOG_BACKWARDS_READ
|
46
|
-
|
48
|
+
|
49
|
+
# Begin reading from a specific record.
|
50
|
+
SEEK_READ = EVENTLOG_SEEK_READ
|
51
|
+
|
52
|
+
# Read the records sequentially. If this is the first read operation, the
|
53
|
+
# EVENTLOG_FORWARDS_READ or EVENTLOG_BACKWARDS_READ flags determines
|
54
|
+
# which record is read first.
|
47
55
|
SEQUENTIAL_READ = EVENTLOG_SEQUENTIAL_READ
|
56
|
+
|
57
|
+
# Event types
|
48
58
|
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
59
|
+
# Information event, an event that describes the successful operation
|
60
|
+
# of an application, driver or service.
|
61
|
+
SUCCESS = EVENTLOG_SUCCESS
|
62
|
+
|
63
|
+
# Error event, an event that indicates a significant problem such as
|
64
|
+
# loss of data or functionality.
|
65
|
+
ERROR = EVENTLOG_ERROR_TYPE
|
66
|
+
|
67
|
+
# Warning event, an event that is not necessarily significant but may
|
68
|
+
# indicate a possible future problem.
|
69
|
+
WARN = EVENTLOG_WARNING_TYPE
|
70
|
+
|
71
|
+
# Information event, an event that describes the successful operation
|
72
|
+
# of an application, driver or service.
|
73
|
+
INFO = EVENTLOG_INFORMATION_TYPE
|
74
|
+
|
75
|
+
# Success audit event, an event that records an audited security attempt
|
76
|
+
# that is successful.
|
77
|
+
AUDIT_SUCCESS = EVENTLOG_AUDIT_SUCCESS
|
78
|
+
|
79
|
+
# Failure audit event, an event that records an audited security attempt
|
80
|
+
# that fails.
|
81
|
+
AUDIT_FAILURE = EVENTLOG_AUDIT_FAILURE
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# :stopdoc:
|
56
86
|
|
57
87
|
BUFFER_SIZE = 1024 * 64
|
58
88
|
MAX_SIZE = 256
|
59
89
|
MAX_STRINGS = 16
|
60
90
|
BASE_KEY = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"
|
61
91
|
|
92
|
+
# :startdoc:
|
93
|
+
|
94
|
+
public
|
95
|
+
|
62
96
|
# The EventLogStruct encapsulates a single event log record.
|
63
97
|
EventLogStruct = Struct.new('EventLogStruct', :record_number,
|
64
98
|
:time_generated, :time_written, :event_id, :event_type, :category,
|
@@ -95,7 +129,7 @@ module Win32
|
|
95
129
|
@server = server
|
96
130
|
@file = file
|
97
131
|
|
98
|
-
# Avoid
|
132
|
+
# Avoid potential segfaults from win32-api
|
99
133
|
raise TypeError unless @source.is_a?(String)
|
100
134
|
raise TypeError unless @server.is_a?(String) if @server
|
101
135
|
|
@@ -136,7 +170,7 @@ module Win32
|
|
136
170
|
@source = source
|
137
171
|
@server = server
|
138
172
|
|
139
|
-
# Avoid
|
173
|
+
# Avoid potential segfaults from win32-api
|
140
174
|
raise TypeError unless @file.is_a?(String)
|
141
175
|
raise TypeError unless @source.is_a?(String)
|
142
176
|
raise TypeError unless @server.is_a?(String) if @server
|
@@ -391,8 +425,8 @@ module Win32
|
|
391
425
|
self
|
392
426
|
end
|
393
427
|
|
394
|
-
# Closes the EventLog handle.
|
395
|
-
# the block form of EventLog.new.
|
428
|
+
# Closes the EventLog handle. The handle is automatically closed for you
|
429
|
+
# if you use the block form of EventLog.new.
|
396
430
|
#
|
397
431
|
def close
|
398
432
|
CloseEventLog(@handle)
|
@@ -432,8 +466,7 @@ module Win32
|
|
432
466
|
total = [0].pack('L')
|
433
467
|
|
434
468
|
unless GetNumberOfEventLogRecords(@handle, total)
|
435
|
-
error = 'GetNumberOfEventLogRecords() failed: '
|
436
|
-
error += get_last_error
|
469
|
+
error = 'GetNumberOfEventLogRecords() failed: ' + get_last_error
|
437
470
|
raise Error, error
|
438
471
|
end
|
439
472
|
|
@@ -456,7 +489,7 @@ module Win32
|
|
456
489
|
@handle = OpenEventLog(@server, @source)
|
457
490
|
|
458
491
|
if @handle == 0
|
459
|
-
error =
|
492
|
+
error = 'OpenEventLog() failed: ' + get_last_error
|
460
493
|
raise Error, error
|
461
494
|
end
|
462
495
|
|
@@ -811,7 +844,7 @@ module Win32
|
|
811
844
|
'error'
|
812
845
|
when EVENTLOG_WARNING_TYPE
|
813
846
|
'warning'
|
814
|
-
when EVENTLOG_INFORMATION_TYPE
|
847
|
+
when EVENTLOG_INFORMATION_TYPE, EVENTLOG_SUCCESS
|
815
848
|
'information'
|
816
849
|
when EVENTLOG_AUDIT_SUCCESS
|
817
850
|
'audit_success'
|
@@ -1112,4 +1145,4 @@ module Win32
|
|
1112
1145
|
[va_list0, buf.nstrip]
|
1113
1146
|
end
|
1114
1147
|
end
|
1115
|
-
end
|
1148
|
+
end
|
data/lib/win32/mc.rb
CHANGED
@@ -1,10 +1,23 @@
|
|
1
|
+
# The Win32 module serves as a namespace only.
|
1
2
|
module Win32
|
3
|
+
|
4
|
+
# The MC class encapsulates the mc (eventlog message compiler) commands.
|
2
5
|
class MC
|
6
|
+
|
7
|
+
# Raised if any of the MC methods fail.
|
3
8
|
class Error < StandardError; end;
|
4
9
|
|
5
|
-
|
10
|
+
# The version of the win32-mc library.
|
11
|
+
VERSION = '0.1.5'
|
6
12
|
|
7
|
-
|
13
|
+
# The name of the message category file initially processed.
|
14
|
+
attr_accessor :mc_file
|
15
|
+
|
16
|
+
# The name of the resource file generated by the mc command.
|
17
|
+
attr_accessor :res_file
|
18
|
+
|
19
|
+
# The name of the dll file generated by the link command.
|
20
|
+
attr_accessor :dll_file
|
8
21
|
|
9
22
|
# Accepts three file names as arguments and returns an MC object. The
|
10
23
|
# +mc_file+ is the name of the .mc file to be used to ultimately
|
@@ -87,17 +100,17 @@ module Win32
|
|
87
100
|
end
|
88
101
|
end
|
89
102
|
|
90
|
-
if $
|
91
|
-
include Win32
|
92
|
-
|
103
|
+
if $PROGRAM_NAME == __FILE__
|
93
104
|
mc_file = ARGV[0]
|
94
105
|
|
95
|
-
|
106
|
+
if mc_file
|
107
|
+
mc_file.chomp!
|
108
|
+
else
|
96
109
|
msg = "Usage: ruby mc.rb 'filename.mc'"
|
97
|
-
raise MC::Error, msg
|
110
|
+
raise Win32::MC::Error, msg
|
98
111
|
end
|
99
112
|
|
100
|
-
m = MC.new(mc_file
|
113
|
+
m = Win32::MC.new(mc_file)
|
101
114
|
m.create_header
|
102
115
|
m.create_res_file
|
103
116
|
m.create_dll_file
|
data/misc/install_msg.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
##############################################################################
|
2
|
+
# install_msg.rb
|
3
|
+
#
|
4
|
+
# This script will create a 'RubyMsg' event source in your registry. All of
|
5
|
+
# the relevant files will be copied to the 'rubymsg' directory under C:\ruby,
|
6
|
+
# or wherever your toplevel Ruby installation directory is located. By
|
7
|
+
# default, this will be installed in the 'Application' log. If you wish to
|
8
|
+
# change that, change the word 'Application' to either 'Security' or 'System'
|
9
|
+
# (or your own custom log).
|
10
|
+
#
|
11
|
+
# DO NOT MOVE THE DLL FILE ONCE IT IS INSTALLED. If you do, you will have
|
12
|
+
# to delete the registry entry and reinstall the event source pointing to the
|
13
|
+
# proper directory.
|
14
|
+
#
|
15
|
+
# You should only run this script *after* you have installed win32-eventlog.
|
16
|
+
##############################################################################
|
17
|
+
require "rbconfig"
|
18
|
+
require "fileutils"
|
19
|
+
require "win32/eventlog"
|
20
|
+
require "win32/mc"
|
21
|
+
include Win32
|
22
|
+
include Config
|
23
|
+
|
24
|
+
prefix = CONFIG["prefix"]
|
25
|
+
msgdir = prefix + '/rubymsg'
|
26
|
+
msgfile = 'rubymsg.mc'
|
27
|
+
|
28
|
+
Dir.mkdir(msgdir) unless File.exists?(msgdir)
|
29
|
+
FileUtils.cp("lib/rubymsg.mc",msgdir)
|
30
|
+
Dir.chdir(msgdir)
|
31
|
+
|
32
|
+
m = MC.new(msgfile)
|
33
|
+
m.create_all
|
34
|
+
|
35
|
+
puts ".dll created"
|
36
|
+
|
37
|
+
dll_file = File.expand_path(m.dll_file)
|
38
|
+
|
39
|
+
# Change 'Application' to whatever you feel is appropriate
|
40
|
+
EventLog.add_event_source(
|
41
|
+
'source' => "Application",
|
42
|
+
'key_name' => "RubyMsg",
|
43
|
+
'category_count' => 3,
|
44
|
+
'event_message_file' => dll_file,
|
45
|
+
'category_message_file' => dll_file
|
46
|
+
)
|
47
|
+
|
48
|
+
puts "Event source 'RubyMsg' added to registry"
|
data/misc/rubymsg.mc
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
MessageId=0x1
|
2
|
+
SymbolicName=CATEGORY_ERROR
|
3
|
+
Language=English
|
4
|
+
Error
|
5
|
+
.
|
6
|
+
|
7
|
+
MessageId=0x2
|
8
|
+
SymbolicName=CATEGORY_WARNING
|
9
|
+
Language=English
|
10
|
+
Warning
|
11
|
+
.
|
12
|
+
|
13
|
+
MessageId=0x3
|
14
|
+
SymbolicName=CATEGORY_OUTPUT
|
15
|
+
Language=English
|
16
|
+
Output
|
17
|
+
.
|
18
|
+
|
19
|
+
MessageId=0x4
|
20
|
+
SymbolicName=RUBY_ERROR
|
21
|
+
Language=English
|
22
|
+
Ruby error: %1
|
23
|
+
.
|
24
|
+
|
25
|
+
MessageId=0x5
|
26
|
+
SymbolicName=RUBY_WARNING
|
27
|
+
Language=English
|
28
|
+
Ruby warning: %1
|
29
|
+
.
|
30
|
+
|
31
|
+
MessageId=0x6
|
32
|
+
SymbolicName=RUBY_OUTPUT
|
33
|
+
Language=English
|
34
|
+
Ruby output: %1
|
35
|
+
.
|
data/test/test_eventlog.rb
CHANGED
@@ -7,25 +7,27 @@
|
|
7
7
|
#############################################################################
|
8
8
|
require 'rubygems'
|
9
9
|
gem 'test-unit'
|
10
|
+
|
10
11
|
require 'test/unit'
|
11
12
|
require 'win32/eventlog'
|
12
13
|
require 'socket'
|
13
14
|
include Win32
|
14
15
|
|
15
|
-
print "\nRelax - this will take a few moments\n\n"
|
16
|
-
|
17
16
|
class TC_EventLog < Test::Unit::TestCase
|
17
|
+
def self.startup
|
18
|
+
@@hostname = Socket.gethostname
|
19
|
+
end
|
20
|
+
|
18
21
|
def setup
|
19
22
|
@log = EventLog.new('Application')
|
20
23
|
@logfile = 'temp.evt'
|
21
24
|
@bakfile = 'C:\event_log.bak'
|
22
|
-
@hostname = Socket.gethostname
|
23
25
|
@records = []
|
24
26
|
@last = nil
|
25
27
|
end
|
26
28
|
|
27
29
|
def test_version
|
28
|
-
assert_equal('0.5.
|
30
|
+
assert_equal('0.5.1', EventLog::VERSION)
|
29
31
|
end
|
30
32
|
|
31
33
|
# Use the alias to validate it as well.
|
@@ -34,18 +36,18 @@ class TC_EventLog < Test::Unit::TestCase
|
|
34
36
|
assert_nothing_raised{ EventLog.open }
|
35
37
|
assert_nothing_raised{ EventLog.open{ |log| } }
|
36
38
|
assert_nothing_raised{ EventLog.open('System') }
|
37
|
-
assert_nothing_raised{ EventLog.open('System',
|
39
|
+
assert_nothing_raised{ EventLog.open('System', @@hostname) }
|
38
40
|
end
|
39
41
|
|
40
42
|
def test_constructor_expected_errors
|
41
|
-
assert_raises(EventLog::Error){ EventLog.new('System',
|
43
|
+
assert_raises(EventLog::Error){ EventLog.new('System', @@hostname, 'foo') }
|
42
44
|
assert_raises(TypeError){ EventLog.open(1) }
|
43
45
|
assert_raises(TypeError){ EventLog.open('System', 1) }
|
44
46
|
end
|
45
47
|
|
46
48
|
def test_constructor_instance_variables
|
47
|
-
assert_nothing_raised{ @log = EventLog.new('Application',
|
48
|
-
assert_equal(
|
49
|
+
assert_nothing_raised{ @log = EventLog.new('Application', @@hostname) }
|
50
|
+
assert_equal(@@hostname, @log.server)
|
49
51
|
assert_equal('Application', @log.source)
|
50
52
|
end
|
51
53
|
|
@@ -85,7 +87,7 @@ class TC_EventLog < Test::Unit::TestCase
|
|
85
87
|
assert_nothing_raised{ EventLog.read("Application", nil){ break } }
|
86
88
|
assert_nothing_raised{ EventLog.read("Application", nil, nil){ break } }
|
87
89
|
assert_nothing_raised{ EventLog.read("Application", nil, nil, 10){ break } }
|
88
|
-
end
|
90
|
+
end
|
89
91
|
|
90
92
|
def test_class_read_expected_errors
|
91
93
|
assert_raises(ArgumentError){
|
@@ -113,7 +115,7 @@ class TC_EventLog < Test::Unit::TestCase
|
|
113
115
|
@records = EventLog.read(nil, nil, flags, @last)
|
114
116
|
}
|
115
117
|
assert_equal(10, @records.length)
|
116
|
-
end
|
118
|
+
end
|
117
119
|
|
118
120
|
# This test could fail, since a record number + 10 may not actually exist.
|
119
121
|
def test_seek_read_backwards
|
@@ -122,6 +124,11 @@ class TC_EventLog < Test::Unit::TestCase
|
|
122
124
|
assert_nothing_raised{ @records = EventLog.read(nil, nil, flags, @last) }
|
123
125
|
assert_equal(11, @records.length)
|
124
126
|
end
|
127
|
+
|
128
|
+
def test_eventlog_struct_is_frozen
|
129
|
+
EventLog.read{ |log| @entry = log; break }
|
130
|
+
assert_true(@entry.frozen?)
|
131
|
+
end
|
125
132
|
|
126
133
|
def test_server
|
127
134
|
assert_respond_to(@log, :server)
|
@@ -217,10 +224,13 @@ class TC_EventLog < Test::Unit::TestCase
|
|
217
224
|
|
218
225
|
def teardown
|
219
226
|
@log.close rescue nil
|
220
|
-
File.delete(@bakfile)
|
227
|
+
File.delete(@bakfile) if File.exists?(@bakfile)
|
221
228
|
@logfile = nil
|
222
|
-
@hostname = nil
|
223
229
|
@records = nil
|
224
230
|
@last = nil
|
225
231
|
end
|
232
|
+
|
233
|
+
def self.shutdown
|
234
|
+
@@hostname = nil
|
235
|
+
end
|
226
236
|
end
|
data/test/test_mc.rb
CHANGED
@@ -8,25 +8,19 @@
|
|
8
8
|
############################################################################
|
9
9
|
require 'rubygems'
|
10
10
|
gem 'test-unit'
|
11
|
+
|
11
12
|
require 'test/unit'
|
12
13
|
require 'win32/mc'
|
13
14
|
require 'ptools'
|
14
15
|
include Win32
|
15
16
|
|
16
17
|
class TC_Win32_MC < Test::Unit::TestCase
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
24
|
-
|
25
|
-
def shutdown
|
26
|
-
@@mc_cmd = nil
|
27
|
-
@@rc_cmd = nil
|
28
|
-
@@link_cmd = nil
|
29
|
-
end
|
18
|
+
def self.startup
|
19
|
+
Dir.chdir(File.expand_path(File.dirname(__FILE__)))
|
20
|
+
|
21
|
+
@@mc_cmd = File.which('mc')
|
22
|
+
@@rc_cmd = File.which('rc')
|
23
|
+
@@link_cmd = File.which('link')
|
30
24
|
end
|
31
25
|
|
32
26
|
def setup
|
@@ -34,7 +28,7 @@ class TC_Win32_MC < Test::Unit::TestCase
|
|
34
28
|
end
|
35
29
|
|
36
30
|
def test_01_version
|
37
|
-
assert_equal('0.1.
|
31
|
+
assert_equal('0.1.5', MC::VERSION)
|
38
32
|
end
|
39
33
|
|
40
34
|
def test_02_create_header
|
@@ -62,6 +56,12 @@ class TC_Win32_MC < Test::Unit::TestCase
|
|
62
56
|
|
63
57
|
def teardown
|
64
58
|
@mc = nil
|
65
|
-
File.delete('foo.dll')
|
59
|
+
File.delete('foo.dll') if File.exists?('foo.dll')
|
66
60
|
end
|
61
|
+
|
62
|
+
def self.shutdown
|
63
|
+
@@mc_cmd = nil
|
64
|
+
@@rc_cmd = nil
|
65
|
+
@@link_cmd = nil
|
66
|
+
end
|
67
67
|
end
|
data/win32-eventlog.gemspec
CHANGED
@@ -1,27 +1,33 @@
|
|
1
|
-
require
|
1
|
+
require 'rubygems'
|
2
2
|
|
3
3
|
spec = Gem::Specification.new do |gem|
|
4
|
-
gem.name
|
5
|
-
gem.version
|
6
|
-
gem.authors
|
7
|
-
gem.
|
8
|
-
gem.
|
9
|
-
gem.
|
10
|
-
gem.
|
11
|
-
gem.
|
12
|
-
gem.test_files
|
13
|
-
gem.has_rdoc
|
4
|
+
gem.name = 'win32-eventlog'
|
5
|
+
gem.version = '0.5.1'
|
6
|
+
gem.authors = ['Daniel J. Berger', 'Park Heesob']
|
7
|
+
gem.license = 'Artistic 2.0'
|
8
|
+
gem.email = 'djberg96@gmail.com'
|
9
|
+
gem.homepage = 'http://www.rubyforge.org/projects/win32utils'
|
10
|
+
gem.platform = Gem::Platform::RUBY
|
11
|
+
gem.summary = 'Interface for the MS Windows Event Log.'
|
12
|
+
gem.test_files = Dir['test/*.rb']
|
13
|
+
gem.has_rdoc = true
|
14
|
+
gem.files = Dir['**/*'].reject{ |f| f.include?('CVS') }
|
15
|
+
|
14
16
|
gem.rubyforge_project = 'win32utils'
|
15
|
-
gem.
|
16
|
-
gem.files.reject! { |fn| fn.include? "CVS" }
|
17
|
-
gem.require_path = "lib"
|
18
|
-
gem.extra_rdoc_files = ["README", "CHANGES", "MANIFEST", "doc/tutorial.txt"]
|
19
|
-
gem.add_dependency("windows-pr", ">= 0.9.3")
|
20
|
-
gem.add_dependency("ptools", ">= 1.1.6")
|
21
|
-
gem.add_dependency("test-unit", ">= 2.0.0")
|
22
|
-
end
|
17
|
+
gem.extra_rdoc_files = ['README', 'CHANGES', 'MANIFEST', 'doc/tutorial.txt']
|
23
18
|
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
gem.add_dependency('windows-pr', '>= 0.9.3')
|
20
|
+
gem.add_development_dependency('ptools', '>= 1.1.6')
|
21
|
+
gem.add_development_dependency('test-unit', '>= 2.0.3')
|
22
|
+
|
23
|
+
gem.description = <<-EOF
|
24
|
+
The win32-eventlog library provides an interface to the MS Windows event
|
25
|
+
log. Event logging provides a standard, centralized way for applications
|
26
|
+
(and the operating system) to record important software and hardware
|
27
|
+
events. The event-logging service stores events from various sources in a
|
28
|
+
single collection called an event log. This library allows you to inspect
|
29
|
+
existing logs as well as create new ones.
|
30
|
+
EOF
|
27
31
|
end
|
32
|
+
|
33
|
+
Gem::Builder.new(spec).build
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: win32-eventlog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel J. Berger
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date:
|
13
|
+
date: 2009-08-08 00:00:00 -06:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
version:
|
26
26
|
- !ruby/object:Gem::Dependency
|
27
27
|
name: ptools
|
28
|
-
type: :
|
28
|
+
type: :development
|
29
29
|
version_requirement:
|
30
30
|
version_requirements: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
@@ -35,15 +35,15 @@ dependencies:
|
|
35
35
|
version:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: test-unit
|
38
|
-
type: :
|
38
|
+
type: :development
|
39
39
|
version_requirement:
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
42
|
- - ">="
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
version: 2.0.
|
44
|
+
version: 2.0.3
|
45
45
|
version:
|
46
|
-
description:
|
46
|
+
description: " The win32-eventlog library provides an interface to the MS Windows event\n log. Event logging provides a standard, centralized way for applications\n (and the operating system) to record important software and hardware\n events. The event-logging service stores events from various sources in a\n single collection called an event log. This library allows you to inspect\n existing logs as well as create new ones.\n"
|
47
47
|
email: djberg96@gmail.com
|
48
48
|
executables: []
|
49
49
|
|
@@ -55,25 +55,26 @@ extra_rdoc_files:
|
|
55
55
|
- MANIFEST
|
56
56
|
- doc/tutorial.txt
|
57
57
|
files:
|
58
|
+
- CHANGES
|
59
|
+
- doc/tutorial.txt
|
60
|
+
- examples/example_notify.rb
|
61
|
+
- examples/example_read.rb
|
62
|
+
- examples/example_write.rb
|
58
63
|
- lib/win32/eventlog.rb
|
59
64
|
- lib/win32/mc.rb
|
60
|
-
- test/foo.mc
|
61
|
-
- test/test_eventlog.rb
|
62
|
-
- test/test_mc.rb
|
63
|
-
- CHANGES
|
64
|
-
- doc
|
65
|
-
- examples
|
66
|
-
- lib
|
67
65
|
- MANIFEST
|
68
|
-
- misc
|
66
|
+
- misc/install_msg.rb
|
67
|
+
- misc/rubymsg.mc
|
69
68
|
- Rakefile
|
70
69
|
- README
|
71
|
-
- test
|
72
|
-
-
|
70
|
+
- test/foo.mc
|
71
|
+
- test/test_eventlog.rb
|
72
|
+
- test/test_mc.rb
|
73
73
|
- win32-eventlog.gemspec
|
74
|
-
- doc/tutorial.txt
|
75
74
|
has_rdoc: true
|
76
75
|
homepage: http://www.rubyforge.org/projects/win32utils
|
76
|
+
licenses:
|
77
|
+
- Artistic 2.0
|
77
78
|
post_install_message:
|
78
79
|
rdoc_options: []
|
79
80
|
|
@@ -94,9 +95,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
95
|
requirements: []
|
95
96
|
|
96
97
|
rubyforge_project: win32utils
|
97
|
-
rubygems_version: 1.
|
98
|
+
rubygems_version: 1.3.5
|
98
99
|
signing_key:
|
99
|
-
specification_version:
|
100
|
+
specification_version: 3
|
100
101
|
summary: Interface for the MS Windows Event Log.
|
101
102
|
test_files:
|
102
103
|
- test/test_eventlog.rb
|
data/win32-eventlog-0.5.0.gem
DELETED
File without changes
|