win32-eventlog 0.4.2
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 +139 -0
- data/MANIFEST +22 -0
- data/README +63 -0
- data/doc/tutorial.txt +140 -0
- data/lib/win32/eventlog.rb +754 -0
- data/lib/win32/mc.rb +104 -0
- data/lib/win32/test.rb +8 -0
- data/test/foo.mc +24 -0
- data/test/tc_eventlog.rb +228 -0
- data/test/tc_mc.rb +49 -0
- data/test/ts_all.rb +7 -0
- metadata +68 -0
data/lib/win32/mc.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
module Win32
|
2
|
+
class MCError < StandardError; end
|
3
|
+
class MC
|
4
|
+
VERSION = '0.1.2'
|
5
|
+
|
6
|
+
attr_accessor :mc_file, :res_file, :dll_file
|
7
|
+
|
8
|
+
# Accepts three file names as arguments and returns an MC object. The
|
9
|
+
# +mc_file+ is the name of the .mc file to be used to ultimately
|
10
|
+
# generate the .dll file.
|
11
|
+
#
|
12
|
+
# If +res_file+ or +dll_file+ are not specified, then the basename
|
13
|
+
# of +mc_file+ is used to generate their names, with .res and .dll
|
14
|
+
# extensions, respectively.
|
15
|
+
#
|
16
|
+
def initialize(mc_file, res_file=nil, dll_file=nil)
|
17
|
+
@mc_file = mc_file
|
18
|
+
|
19
|
+
if res_file
|
20
|
+
@res_file = res_file
|
21
|
+
else
|
22
|
+
@res_file = File.basename(mc_file, '.mc') + '.res'
|
23
|
+
end
|
24
|
+
|
25
|
+
if dll_file
|
26
|
+
@dll_file = dll_file
|
27
|
+
else
|
28
|
+
@dll_file = File.basename(mc_file, '.mc') + '.dll'
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Uses the message compiler (mc) program to generate the .h and .rc
|
33
|
+
# files based on the .mc (message category) file. This method must
|
34
|
+
# be called before MC#create_res_file or MC#create_dll_file.
|
35
|
+
#
|
36
|
+
def create_header
|
37
|
+
system("mc #{@mc_file}")
|
38
|
+
end
|
39
|
+
|
40
|
+
# Creates the .res (resource) file from the .rc file generated by the
|
41
|
+
# MC#create_header method. Raises an MCError if the .rc file is not
|
42
|
+
# found.
|
43
|
+
#
|
44
|
+
def create_res_file
|
45
|
+
rc_file = File.basename(@mc_file, '.mc') + '.rc'
|
46
|
+
unless File.exists?(rc_file)
|
47
|
+
raise MCError, "No .rc file found: #{@rc_file}"
|
48
|
+
end
|
49
|
+
system("rc -r -fo #{@res_file} #{rc_file}")
|
50
|
+
end
|
51
|
+
|
52
|
+
# Creates the .dll file from the .res file generated by the
|
53
|
+
# MC#create_res_file method. Raises an MCError if the .res file is not
|
54
|
+
# found.
|
55
|
+
#
|
56
|
+
def create_dll_file
|
57
|
+
unless File.exists?(@res_file)
|
58
|
+
raise MCError, "No .res file found: #{@res_file}"
|
59
|
+
end
|
60
|
+
system("link -dll -noentry -out:#{@dll_file} #{@res_file}")
|
61
|
+
end
|
62
|
+
|
63
|
+
# A shortcut for MC#create_header + MC#create_res_file +
|
64
|
+
# MC#create_dll_file.
|
65
|
+
#
|
66
|
+
def create_all
|
67
|
+
create_header
|
68
|
+
create_res_file
|
69
|
+
create_dll_file
|
70
|
+
end
|
71
|
+
|
72
|
+
# Delete .h, .rc and .res files created from the corresponding
|
73
|
+
# .mc file (but *not* the .dll file). This also deletes all MSG*.bin
|
74
|
+
# files in the current directory.
|
75
|
+
#
|
76
|
+
def clean
|
77
|
+
base = File.basename(@mc_file, '.mc')
|
78
|
+
%w/.h .rc .res/.each do |ext|
|
79
|
+
file = base + ext
|
80
|
+
File.delete(file) if File.exists?(file)
|
81
|
+
end
|
82
|
+
Dir["MSG*.bin"].each do |binfile|
|
83
|
+
File.delete(binfile)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
if $0 == __FILE__
|
90
|
+
include Win32
|
91
|
+
|
92
|
+
mc_file = ARGV[0]
|
93
|
+
|
94
|
+
unless mc_file
|
95
|
+
msg = "Usage: ruby mc.rb 'filename.mc'"
|
96
|
+
raise MCError, msg
|
97
|
+
end
|
98
|
+
|
99
|
+
m = MC.new(mc_file)
|
100
|
+
m.create_header
|
101
|
+
m.create_res_file
|
102
|
+
m.create_dll_file
|
103
|
+
puts "MC finished"
|
104
|
+
end
|
data/lib/win32/test.rb
ADDED
data/test/foo.mc
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
MessageId=0x1
|
2
|
+
SymbolicName=CATEGORY_HELLO
|
3
|
+
Language=English
|
4
|
+
Foohello
|
5
|
+
.
|
6
|
+
|
7
|
+
MessageId=0x2
|
8
|
+
SymbolicName=CATEGORY_WORLD
|
9
|
+
Language=English
|
10
|
+
Fooworld
|
11
|
+
.
|
12
|
+
|
13
|
+
MessageId=0x3
|
14
|
+
SymbolicName=FOO_ERROR
|
15
|
+
Language=English
|
16
|
+
Foo error: %1
|
17
|
+
.
|
18
|
+
|
19
|
+
MessageId=0x4
|
20
|
+
SymbolicName=FOO_WARN
|
21
|
+
Language=English
|
22
|
+
Foo warning: %1
|
23
|
+
.
|
24
|
+
|
data/test/tc_eventlog.rb
ADDED
@@ -0,0 +1,228 @@
|
|
1
|
+
###################################################
|
2
|
+
# tc_eventlog.rb
|
3
|
+
#
|
4
|
+
# Test case for the win32-eventlog package.
|
5
|
+
###################################################
|
6
|
+
Dir.chdir('..') if File.basename(Dir.pwd) == 'test'
|
7
|
+
$LOAD_PATH.unshift Dir.pwd
|
8
|
+
$LOAD_PATH.unshift Dir.pwd + '/lib'
|
9
|
+
Dir.chdir('test') rescue nil
|
10
|
+
|
11
|
+
require 'test/unit'
|
12
|
+
require 'win32/eventlog'
|
13
|
+
require 'socket'
|
14
|
+
include Win32
|
15
|
+
|
16
|
+
print "\nRelax - this will take a few moments\n\n"
|
17
|
+
|
18
|
+
class TC_EventLog < Test::Unit::TestCase
|
19
|
+
def setup
|
20
|
+
@log = EventLog.new('Application')
|
21
|
+
@logfile = 'temp.evt'
|
22
|
+
@bakfile = 'C:\event_log.bak'
|
23
|
+
@hostname = Socket.gethostname
|
24
|
+
@records = []
|
25
|
+
@last = nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_version
|
29
|
+
assert_equal('0.4.2', EventLog::VERSION)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Use the alias to validate it as well.
|
33
|
+
def test_constructor
|
34
|
+
assert_respond_to(EventLog, :open)
|
35
|
+
assert_nothing_raised{ EventLog.open }
|
36
|
+
assert_nothing_raised{ EventLog.open{ |log| } }
|
37
|
+
assert_nothing_raised{ EventLog.open('System') }
|
38
|
+
assert_nothing_raised{ EventLog.open('System', @hostname) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_constructor_expected_errors
|
42
|
+
assert_raises(EventLogError){ EventLog.new('System', @hostname, 'foo') }
|
43
|
+
assert_raises(TypeError){ EventLog.open(1) }
|
44
|
+
assert_raises(TypeError){ EventLog.open('System', 1) }
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_constructor_instance_variables
|
48
|
+
assert_nothing_raised{ @log = EventLog.new('Application', @hostname) }
|
49
|
+
assert_equal(@hostname, @log.server)
|
50
|
+
assert_equal('Application', @log.source)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_open_backup
|
54
|
+
assert_respond_to(EventLog, :open_backup)
|
55
|
+
assert_nothing_raised{ EventLog.new('Application').backup(@bakfile) }
|
56
|
+
assert_nothing_raised{ @log = EventLog.open_backup(@bakfile) }
|
57
|
+
assert_kind_of(EventLog, @log)
|
58
|
+
assert_nothing_raised{ @log.read{ break } }
|
59
|
+
assert_nothing_raised{ @log.close }
|
60
|
+
end
|
61
|
+
|
62
|
+
# Ensure that an Array is returned in non-block form and that none of the
|
63
|
+
# descriptions are nil.
|
64
|
+
#
|
65
|
+
# The test for descriptions was added as a result of ruby-talk:116528.
|
66
|
+
# Thanks go to Joey Gibson for the spot. The test for unique record
|
67
|
+
# numbers was added to ensure no dups.
|
68
|
+
#
|
69
|
+
def test_class_read_verification
|
70
|
+
assert_nothing_raised{ @array = EventLog.read }
|
71
|
+
assert_kind_of(Array, @array)
|
72
|
+
|
73
|
+
record_numbers = []
|
74
|
+
@array.each{ |log|
|
75
|
+
assert_not_nil(log.description)
|
76
|
+
assert_equal(false, record_numbers.include?(log.record_number))
|
77
|
+
record_numbers << log.record_number
|
78
|
+
}
|
79
|
+
end
|
80
|
+
|
81
|
+
# I've added explicit breaks because an event log could be rather large.
|
82
|
+
#
|
83
|
+
def test_class_read_basic
|
84
|
+
assert_nothing_raised{ EventLog.read{ break } }
|
85
|
+
assert_nothing_raised{ EventLog.read("Application"){ break } }
|
86
|
+
assert_nothing_raised{ EventLog.read("Application", nil){ break } }
|
87
|
+
assert_nothing_raised{ EventLog.read("Application", nil, nil){ break } }
|
88
|
+
assert_nothing_raised{ EventLog.read("Application", nil, nil, 10){ break } }
|
89
|
+
end
|
90
|
+
|
91
|
+
def test_class_read_expected_errors
|
92
|
+
assert_raises(ArgumentError){
|
93
|
+
EventLog.read("Application", nil, nil, nil, nil){}
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_read
|
98
|
+
flags = EventLog::FORWARDS_READ | EventLog::SEQUENTIAL_READ
|
99
|
+
assert_respond_to(@log, :read)
|
100
|
+
assert_nothing_raised{ @log.read{ break } }
|
101
|
+
assert_nothing_raised{ @log.read(flags){ break } }
|
102
|
+
assert_nothing_raised{ @log.read(flags, 500){ break } }
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_read_expected_errors
|
106
|
+
flags = EventLog::FORWARDS_READ | EventLog::SEQUENTIAL_READ
|
107
|
+
assert_raises(ArgumentError){ @log.read(flags, 500, 'foo') }
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_seek_read
|
111
|
+
flags = EventLog::SEEK_READ | EventLog::FORWARDS_READ
|
112
|
+
assert_nothing_raised{ @last = @log.total_records }
|
113
|
+
assert_nothing_raised{
|
114
|
+
@records = EventLog.read(nil, nil, flags, @last - 10)
|
115
|
+
}
|
116
|
+
assert_equal(11, @records.length)
|
117
|
+
assert_equal(@last, @records.last.record_number)
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_seek_read_backwards
|
121
|
+
flags = EventLog::SEEK_READ | EventLog::BACKWARDS_READ
|
122
|
+
assert_nothing_raised{ @records = EventLog.read(nil, nil, flags, 10) }
|
123
|
+
assert_equal(10, @records.length)
|
124
|
+
assert_equal(10, @records.first.record_number)
|
125
|
+
assert_equal(1, @records.last.record_number)
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_server
|
129
|
+
assert_respond_to(@log, :server)
|
130
|
+
assert_raises(NoMethodError){ @log.server = 'foo' }
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_source
|
134
|
+
assert_respond_to(@log, :source)
|
135
|
+
assert_kind_of(String, @log.source)
|
136
|
+
assert_raises(NoMethodError){ @log.source = 'foo' }
|
137
|
+
end
|
138
|
+
|
139
|
+
def test_file
|
140
|
+
assert_respond_to(@log, :file)
|
141
|
+
assert_nil(@log.file)
|
142
|
+
assert_raises(NoMethodError){ @log.file = 'foo' }
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_backup
|
146
|
+
assert_respond_to(@log, :backup)
|
147
|
+
assert_nothing_raised{ @log.backup(@bakfile) }
|
148
|
+
assert(File.exists?(@bakfile))
|
149
|
+
assert_raises(EventLogError){ @log.backup(@bakfile) }
|
150
|
+
end
|
151
|
+
|
152
|
+
# Since I don't want to actually clear anyone's event log, I can't really
|
153
|
+
# verify that it works.
|
154
|
+
#
|
155
|
+
def test_clear
|
156
|
+
assert_respond_to(@log, :clear)
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_full
|
160
|
+
assert_respond_to(@log, :full?)
|
161
|
+
assert_nothing_raised{ @log.full? }
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_close
|
165
|
+
assert_respond_to(@log, :close)
|
166
|
+
assert_nothing_raised{ @log.close }
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_oldest_record_number
|
170
|
+
assert_respond_to(@log, :oldest_record_number)
|
171
|
+
assert_kind_of(Fixnum, @log.oldest_record_number)
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_total_records
|
175
|
+
assert_respond_to(@log, :total_records)
|
176
|
+
assert_kind_of(Fixnum, @log.total_records)
|
177
|
+
end
|
178
|
+
|
179
|
+
# We can't test that this method actually executes properly since it goes
|
180
|
+
# into an endless loop.
|
181
|
+
#
|
182
|
+
def test_tail
|
183
|
+
assert_respond_to(@log, :tail)
|
184
|
+
assert_raises(EventLogError){ @log.tail } # requires block
|
185
|
+
end
|
186
|
+
|
187
|
+
# We can't test that this method actually executes properly since it goes
|
188
|
+
# into an endless loop.
|
189
|
+
#
|
190
|
+
def test_notify_change
|
191
|
+
assert_respond_to(@log, :notify_change)
|
192
|
+
assert_raises(EventLogError){ @log.notify_change } # requires block
|
193
|
+
end
|
194
|
+
|
195
|
+
# I can't really do more in depth testing for this method since there
|
196
|
+
# isn't an event source I can reliably and safely write to.
|
197
|
+
#
|
198
|
+
def test_report_event
|
199
|
+
assert_respond_to(@log, :report_event)
|
200
|
+
assert_respond_to(@log, :write) # alias
|
201
|
+
assert_raises(ArgumentError){ @log.report_event }
|
202
|
+
end
|
203
|
+
|
204
|
+
def test_read_event_constants
|
205
|
+
assert_not_nil(EventLog::FORWARDS_READ)
|
206
|
+
assert_not_nil(EventLog::BACKWARDS_READ)
|
207
|
+
assert_not_nil(EventLog::SEEK_READ)
|
208
|
+
assert_not_nil(EventLog::SEQUENTIAL_READ)
|
209
|
+
end
|
210
|
+
|
211
|
+
def test_event_type_constants
|
212
|
+
assert_not_nil(EventLog::SUCCESS)
|
213
|
+
assert_not_nil(EventLog::ERROR)
|
214
|
+
assert_not_nil(EventLog::WARN)
|
215
|
+
assert_not_nil(EventLog::INFO)
|
216
|
+
assert_not_nil(EventLog::AUDIT_SUCCESS)
|
217
|
+
assert_not_nil(EventLog::AUDIT_FAILURE)
|
218
|
+
end
|
219
|
+
|
220
|
+
def teardown
|
221
|
+
@log.close rescue nil
|
222
|
+
File.delete(@bakfile) rescue nil
|
223
|
+
@logfile = nil
|
224
|
+
@hostname = nil
|
225
|
+
@records = nil
|
226
|
+
@last = nil
|
227
|
+
end
|
228
|
+
end
|
data/test/tc_mc.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
############################################################################
|
2
|
+
# tc_mc.rb
|
3
|
+
#
|
4
|
+
# Test suite for the win32-mc package. The tests need to run in a specific
|
5
|
+
# order, hence the numerics added to the method names.
|
6
|
+
############################################################################
|
7
|
+
Dir.chdir('..') if File.basename(Dir.pwd) == 'test'
|
8
|
+
$LOAD_PATH.unshift Dir.pwd
|
9
|
+
$LOAD_PATH.unshift Dir.pwd + '/lib'
|
10
|
+
Dir.chdir('test') rescue nil
|
11
|
+
|
12
|
+
require 'test/unit'
|
13
|
+
require 'win32/mc'
|
14
|
+
include Win32
|
15
|
+
|
16
|
+
class TC_Win32_MC < Test::Unit::TestCase
|
17
|
+
def setup
|
18
|
+
@mc = MC.new('foo.mc')
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_01_version
|
22
|
+
assert_equal('0.1.2', MC::VERSION)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_02_create_header
|
26
|
+
assert_respond_to(@mc, :create_header)
|
27
|
+
assert_nothing_raised{ @mc.create_header }
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_03_create_res_file
|
31
|
+
assert_respond_to(@mc, :create_res_file)
|
32
|
+
assert_nothing_raised{ @mc.create_res_file }
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_04_create_dll_file
|
36
|
+
assert_respond_to(@mc, :create_dll_file)
|
37
|
+
assert_nothing_raised{ @mc.create_dll_file }
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_05_clean
|
41
|
+
assert_respond_to(@mc, :clean)
|
42
|
+
assert_nothing_raised{ @mc.clean }
|
43
|
+
end
|
44
|
+
|
45
|
+
def teardown
|
46
|
+
@mc = nil
|
47
|
+
File.delete('foo.dll') rescue nil
|
48
|
+
end
|
49
|
+
end
|
data/test/ts_all.rb
ADDED
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: win32-eventlog
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.4.2
|
7
|
+
date: 2006-08-06 00:00:00 -06:00
|
8
|
+
summary: Interface for the MS Windows Event Log.
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: djberg96@gmail.com
|
12
|
+
homepage: http://www.rubyforge.org/projects/win32utils
|
13
|
+
rubyforge_project:
|
14
|
+
description: Interface for the MS Windows Event Log.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Daniel J. Berger
|
31
|
+
files:
|
32
|
+
- lib/win32/eventlog.rb
|
33
|
+
- lib/win32/mc.rb
|
34
|
+
- lib/win32/test.rb
|
35
|
+
- test/CVS
|
36
|
+
- test/foo.mc
|
37
|
+
- test/tc_eventlog.rb
|
38
|
+
- test/tc_mc.rb
|
39
|
+
- test/ts_all.rb
|
40
|
+
- CHANGES
|
41
|
+
- CVS
|
42
|
+
- MANIFEST
|
43
|
+
- README
|
44
|
+
- doc/tutorial.txt
|
45
|
+
test_files:
|
46
|
+
- test/ts_all.rb
|
47
|
+
rdoc_options: []
|
48
|
+
|
49
|
+
extra_rdoc_files:
|
50
|
+
- README
|
51
|
+
- CHANGES
|
52
|
+
- doc/tutorial.txt
|
53
|
+
executables: []
|
54
|
+
|
55
|
+
extensions: []
|
56
|
+
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
dependencies:
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: windows-pr
|
62
|
+
version_requirement:
|
63
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: 0.5.0
|
68
|
+
version:
|