win32-eventlog 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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"