win32-eventlog 0.5.3 → 0.6.0

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/lib/win32/mc.rb CHANGED
@@ -1,118 +1,120 @@
1
- # The Win32 module serves as a namespace only.
2
- module Win32
3
-
4
- # The MC class encapsulates the mc (eventlog message compiler) commands.
5
- class MC
6
-
7
- # Raised if any of the MC methods fail.
8
- class Error < StandardError; end;
9
-
10
- # The version of the win32-mc library.
11
- VERSION = '0.1.5'
12
-
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
21
-
22
- # Accepts three file names as arguments and returns an MC object. The
23
- # +mc_file+ is the name of the .mc file to be used to ultimately
24
- # generate the .dll file.
25
- #
26
- # If +res_file+ or +dll_file+ are not specified, then the basename
27
- # of +mc_file+ is used to generate their names, with .res and .dll
28
- # extensions, respectively.
29
- #
30
- def initialize(mc_file, res_file=nil, dll_file=nil)
31
- @mc_file = mc_file
32
-
33
- if res_file
34
- @res_file = res_file
35
- else
36
- @res_file = File.basename(mc_file, '.mc') + '.res'
37
- end
38
-
39
- if dll_file
40
- @dll_file = dll_file
41
- else
42
- @dll_file = File.basename(mc_file, '.mc') + '.dll'
43
- end
44
- end
45
-
46
- # Uses the message compiler (mc) program to generate the .h and .rc
47
- # files based on the .mc (message category) file. This method must
48
- # be called before MC#create_res_file or MC#create_dll_file.
49
- #
50
- def create_header
51
- system("mc #{@mc_file}")
52
- end
53
-
54
- # Creates the .res (resource) file from the .rc file generated by the
55
- # MC#create_header method. Raises an MC::Error if the .rc file is not
56
- # found.
57
- #
58
- def create_res_file
59
- rc_file = File.basename(@mc_file, '.mc') + '.rc'
60
- unless File.exists?(rc_file)
61
- raise MC::Error, "No .rc file found: #{@rc_file}"
62
- end
63
- system("rc -r -fo #{@res_file} #{rc_file}")
64
- end
65
-
66
- # Creates the .dll file from the .res file generated by the
67
- # MC#create_res_file method. Raises an MC::Error if the .res file is not
68
- # found.
69
- #
70
- def create_dll_file
71
- unless File.exists?(@res_file)
72
- raise MC::Error, "No .res file found: #{@res_file}"
73
- end
74
- system("link -dll -noentry -out:#{@dll_file} #{@res_file}")
75
- end
76
-
77
- # A shortcut for MC#create_header + MC#create_res_file +
78
- # MC#create_dll_file.
79
- #
80
- def create_all
81
- create_header
82
- create_res_file
83
- create_dll_file
84
- end
85
-
86
- # Delete .h, .rc and .res files created from the corresponding
87
- # .mc file (but *not* the .dll file). This also deletes all MSG*.bin
88
- # files in the current directory.
89
- #
90
- def clean
91
- base = File.basename(@mc_file, '.mc')
92
- %w/.h .rc .res/.each do |ext|
93
- file = base + ext
94
- File.delete(file) if File.exists?(file)
95
- end
96
- Dir["MSG*.bin"].each do |binfile|
97
- File.delete(binfile)
98
- end
99
- end
100
- end
101
- end
102
-
103
- if $PROGRAM_NAME == __FILE__
104
- mc_file = ARGV[0]
105
-
106
- if mc_file
107
- mc_file.chomp!
108
- else
109
- msg = "Usage: ruby mc.rb 'filename.mc'"
110
- raise Win32::MC::Error, msg
111
- end
112
-
113
- m = Win32::MC.new(mc_file)
114
- m.create_header
115
- m.create_res_file
116
- m.create_dll_file
117
- puts "MC finished"
118
- end
1
+ # The Win32 module serves as a namespace only.
2
+ module Win32
3
+
4
+ # The MC class encapsulates the mc (eventlog message compiler) commands.
5
+ class MC
6
+
7
+ # Raised if any of the MC methods fail.
8
+ class Error < StandardError; end;
9
+
10
+ # The version of the win32-mc library.
11
+ VERSION = '0.1.6'
12
+
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
21
+
22
+ # Accepts three file names as arguments and returns an MC object. The
23
+ # +mc_file+ is the name of the .mc file to be used to ultimately
24
+ # generate the .dll file.
25
+ #
26
+ # If +res_file+ or +dll_file+ are not specified, then the basename
27
+ # of +mc_file+ is used to generate their names, with .res and .dll
28
+ # extensions, respectively.
29
+ #
30
+ def initialize(mc_file, res_file=nil, dll_file=nil)
31
+ @mc_file = mc_file
32
+
33
+ if res_file
34
+ @res_file = res_file
35
+ else
36
+ @res_file = File.basename(mc_file, '.mc') + '.res'
37
+ end
38
+
39
+ if dll_file
40
+ @dll_file = dll_file
41
+ else
42
+ @dll_file = File.basename(mc_file, '.mc') + '.dll'
43
+ end
44
+ end
45
+
46
+ # Uses the message compiler (mc) program to generate the .h and .rc
47
+ # files based on the .mc (message category) file. This method must
48
+ # be called before MC#create_res_file or MC#create_dll_file.
49
+ #
50
+ def create_header
51
+ system("mc #{@mc_file}")
52
+ end
53
+
54
+ # Creates the .res (resource) file from the .rc file generated by the
55
+ # MC#create_header method. Raises an MC::Error if the .rc file is not
56
+ # found.
57
+ #
58
+ def create_res_file
59
+ rc_file = File.basename(@mc_file, '.mc') + '.rc'
60
+ unless File.exists?(rc_file)
61
+ raise MC::Error, "No .rc file found: #{@rc_file}"
62
+ end
63
+ system("rc -r -fo #{@res_file} #{rc_file}")
64
+ end
65
+
66
+ # Creates the .dll file from the .res file generated by the
67
+ # MC#create_res_file method. Raises an MC::Error if the .res file is not
68
+ # found.
69
+ #
70
+ def create_dll_file
71
+ unless File.exists?(@res_file)
72
+ raise MC::Error, "No .res file found: #{@res_file}"
73
+ end
74
+ system("link -dll -noentry -out:#{@dll_file} #{@res_file}")
75
+ end
76
+
77
+ # A shortcut for MC#create_header + MC#create_res_file +
78
+ # MC#create_dll_file.
79
+ #
80
+ def create_all
81
+ create_header
82
+ create_res_file
83
+ create_dll_file
84
+ end
85
+
86
+ # Delete .h, .rc and .res files created from the corresponding
87
+ # .mc file (but *not* the .dll file). This also deletes all MSG*.bin
88
+ # files in the current directory.
89
+ #
90
+ def clean
91
+ base = File.basename(@mc_file, '.mc')
92
+
93
+ %w[.h .rc .res].each do |ext|
94
+ file = base + ext
95
+ File.delete(file) if File.exists?(file)
96
+ end
97
+
98
+ Dir["MSG*.bin"].each do |binfile|
99
+ File.delete(binfile)
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ if $PROGRAM_NAME == __FILE__
106
+ mc_file = ARGV[0]
107
+
108
+ if mc_file
109
+ mc_file.chomp!
110
+ else
111
+ msg = "Usage: ruby mc.rb 'filename.mc'"
112
+ raise Win32::MC::Error, msg
113
+ end
114
+
115
+ m = Win32::MC.new(mc_file)
116
+ m.create_header
117
+ m.create_res_file
118
+ m.create_dll_file
119
+ puts "MC finished"
120
+ end
@@ -0,0 +1,56 @@
1
+ module Windows
2
+ module Constants
3
+ private
4
+
5
+ EVENTLOG_SEQUENTIAL_READ = 0x0001
6
+ EVENTLOG_SEEK_READ = 0x0002
7
+ EVENTLOG_FORWARDS_READ = 0x0004
8
+ EVENTLOG_BACKWARDS_READ = 0x0008
9
+
10
+ EVENTLOG_SUCCESS = 0x0000
11
+ EVENTLOG_ERROR_TYPE = 0x0001
12
+ EVENTLOG_WARNING_TYPE = 0x0002
13
+ EVENTLOG_INFORMATION_TYPE = 0x0004
14
+ EVENTLOG_AUDIT_SUCCESS = 0x0008
15
+ EVENTLOG_AUDIT_FAILURE = 0x0010
16
+
17
+ EVENTLOG_FULL_INFO = 0
18
+
19
+ HKEY_LOCAL_MACHINE = 0x80000002
20
+
21
+ REG_OPTION_NON_VOLATILE = 0
22
+ REG_DWORD = 4
23
+ REG_EXPAND_SZ = 2
24
+
25
+ ERROR_SUCCESS = 0
26
+ ERROR_INSUFFICIENT_BUFFER = 122
27
+
28
+ BUFFER_SIZE = 1024 * 64
29
+ MAX_SIZE = 512
30
+ MAX_STRINGS = 16
31
+ INFINITE = 0xFFFFFFFF
32
+ WAIT_FAILED = 0xFFFFFFFF
33
+
34
+ BASE_KEY = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\"
35
+
36
+ STANDARD_RIGHTS_READ = 0x20000
37
+ STANDARD_RIGHTS_WRITE = 0x20000
38
+ SYNCHRONIZE = 0x100000
39
+
40
+ KEY_QUERY_VALUE = 0x0001
41
+ KEY_SET_VALUE = 0x0002
42
+ KEY_CREATE_SUB_KEY = 0x0004
43
+ KEY_ENUMERATE_SUB_KEYS = 0x0008
44
+ KEY_NOTIFY = 0x0010
45
+
46
+ KEY_WRITE = (STANDARD_RIGHTS_WRITE|KEY_SET_VALUE|KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE)
47
+ KEY_READ = (STANDARD_RIGHTS_READ|KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS| KEY_NOTIFY) & (~SYNCHRONIZE)
48
+
49
+ DONT_RESOLVE_DLL_REFERENCES = 0x00000001
50
+ LOAD_LIBRARY_AS_DATAFILE = 0x00000002
51
+
52
+ FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
53
+ FORMAT_MESSAGE_FROM_HMODULE = 0x00000800
54
+ FORMAT_MESSAGE_ARGUMENT_ARRAY = 0x00002000
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module Functions
5
+ extend FFI::Library
6
+ ffi_lib :advapi32
7
+
8
+ typedef :uintptr_t, :handle
9
+ typedef :uintptr_t, :hkey
10
+ typedef :ulong, :dword
11
+ typedef :ushort, :word
12
+
13
+ attach_function :BackupEventLog, :BackupEventLogA, [:handle, :string], :bool
14
+ attach_function :ClearEventLog, :ClearEventLogA, [:handle, :string], :bool
15
+ attach_function :CloseEventLog, [:handle], :bool
16
+ attach_function :GetOldestEventLogRecord, [:handle, :pointer], :bool
17
+ attach_function :GetEventLogInformation, [:handle, :dword, :pointer, :dword, :pointer], :bool
18
+ attach_function :GetNumberOfEventLogRecords, [:handle, :pointer], :bool
19
+ attach_function :LookupAccountSid, :LookupAccountSidA, [:string, :pointer, :pointer, :pointer, :pointer, :pointer, :pointer], :bool
20
+ attach_function :OpenEventLog, :OpenEventLogA, [:string, :string], :handle
21
+ attach_function :OpenBackupEventLog, :OpenBackupEventLogA, [:string, :string], :handle
22
+ attach_function :NotifyChangeEventLog, [:handle, :handle], :bool
23
+ attach_function :ReadEventLog, :ReadEventLogA, [:handle, :dword, :dword, :buffer_out, :dword, :pointer, :pointer], :bool
24
+ attach_function :RegCloseKey, [:hkey], :long
25
+ attach_function :RegConnectRegistry, :RegConnectRegistryA, [:string, :hkey, :pointer], :long
26
+ attach_function :RegCreateKeyEx, :RegCreateKeyExA, [:hkey, :string, :dword, :string, :dword, :dword, :pointer, :pointer, :pointer], :long
27
+ attach_function :RegisterEventSource, :RegisterEventSourceA, [:string, :string], :handle
28
+ attach_function :RegOpenKeyEx, :RegOpenKeyExA, [:hkey, :string, :dword, :ulong, :pointer], :long
29
+ attach_function :RegQueryValueEx, :RegQueryValueExA, [:hkey, :string, :pointer, :pointer, :pointer, :pointer], :long
30
+ attach_function :RegSetValueEx, :RegSetValueExA, [:hkey, :string, :dword, :dword, :pointer, :dword], :long
31
+ attach_function :ReportEvent, :ReportEventA, [:handle, :word, :word, :dword, :pointer, :word, :dword, :pointer, :pointer], :bool
32
+
33
+ ffi_lib :kernel32
34
+
35
+ attach_function :CloseHandle, [:handle], :bool
36
+ attach_function :CreateEvent, :CreateEventA, [:pointer, :bool, :bool, :string], :handle
37
+ attach_function :ExpandEnvironmentStrings, :ExpandEnvironmentStringsA, [:string, :pointer, :dword], :dword
38
+ attach_function :FormatMessage, :FormatMessageA, [:dword, :uintptr_t, :dword, :dword, :pointer, :dword, :pointer], :dword
39
+ attach_function :FreeLibrary, [:handle], :bool
40
+ attach_function :LoadLibraryEx, :LoadLibraryExA, [:string, :handle, :dword], :handle
41
+ attach_function :WaitForSingleObject, [:handle, :dword], :dword
42
+ attach_function :Wow64DisableWow64FsRedirection, [:pointer], :bool
43
+ attach_function :Wow64RevertWow64FsRedirection, [:ulong], :bool
44
+
45
+ ffi_lib :wevtapi
46
+
47
+ attach_function :EvtClose, [:handle], :bool
48
+ attach_function :EvtOpenPublisherMetadata, [:handle, :buffer_in, :buffer_in, :dword, :dword], :handle
49
+ attach_function :EvtGetPublisherMetadataProperty, [:handle, :int, :dword, :dword, :pointer, :pointer], :bool
50
+ end
51
+ end
@@ -0,0 +1,13 @@
1
+ class String
2
+ # Convenience method for converting strings to UTF-16LE for wide character
3
+ # functions that require it.
4
+ def wincode
5
+ (self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
6
+ end
7
+
8
+ # Read a wide character string up until the first double null, and delete
9
+ # any remaining null characters.
10
+ def read_wide
11
+ self[/^.*?(?=\x00{2})/].delete(0.chr)
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module Structs
5
+ extend FFI::Library
6
+ typedef :ulong, :dword
7
+ typedef :ushort, :word
8
+
9
+ class EVENTLOGRECORD < FFI::Struct
10
+ layout(
11
+ :Length, :dword,
12
+ :Reserved, :dword,
13
+ :RecordNumber, :dword,
14
+ :TimeGenerated, :dword,
15
+ :TimeWritten, :dword,
16
+ :EventID, :dword,
17
+ :EventType, :word,
18
+ :NumStrings, :word,
19
+ :EventCategory, :word,
20
+ :ReservedFlags, :word,
21
+ :ClosingRecordNumber, :dword,
22
+ :StringOffset, :dword,
23
+ :UserSidLength, :dword,
24
+ :UserSidOffset, :dword,
25
+ :DataLength, :dword,
26
+ :DataOffset, :dword
27
+ )
28
+ end
29
+ end
30
+ end
data/misc/install_msg.rb CHANGED
@@ -1,46 +1,46 @@
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
-
23
- msg_dir = File.join(Config::CONFIG['prefix'], 'rubymsg')
24
- msg_file = 'rubymsg.mc'
25
-
26
- Dir.mkdir(msg_dir) unless File.exists?(msg_dir)
27
- FileUtils.cp('misc/rubymsg.mc', msg_dir)
28
- Dir.chdir(msg_dir)
29
-
30
- mc = Win32::MC.new(msg_file)
31
- mc.create_all
32
-
33
- puts ".dll created"
34
-
35
- dll_file = File.expand_path(m.dll_file)
36
-
37
- # Change 'Application' to whatever you feel is appropriate
38
- Win32::EventLog.add_event_source(
39
- :source => "Application",
40
- :key_name => "RubyMsg",
41
- :category_count => 3,
42
- :event_message_file => dll_file,
43
- :category_message_file => dll_file
44
- )
45
-
46
- puts "Event source 'RubyMsg' added to registry"
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 default
7
+ # this will be installed in the 'Application' log. If you wish to change that
8
+ # then change the word 'Application' to either 'Security' or 'System' (or your
9
+ # 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
+
23
+ msg_dir = File.join(RbConfig::CONFIG['prefix'], 'rubymsg')
24
+ msg_file = 'rubymsg.mc'
25
+
26
+ Dir.mkdir(msg_dir) unless File.exists?(msg_dir)
27
+ FileUtils.cp('misc/rubymsg.mc', msg_dir)
28
+ Dir.chdir(msg_dir)
29
+
30
+ mc = Win32::MC.new(msg_file)
31
+ mc.create_all
32
+
33
+ puts ".dll created"
34
+
35
+ dll_file = File.expand_path(mc.dll_file)
36
+
37
+ # Change 'Application' to whatever you feel is appropriate
38
+ Win32::EventLog.add_event_source(
39
+ :source => "Application",
40
+ :key_name => "RubyMsg",
41
+ :category_count => 3,
42
+ :event_message_file => dll_file,
43
+ :category_message_file => dll_file
44
+ )
45
+
46
+ puts "Event source 'RubyMsg' added to registry"