win32-service 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,137 @@
1
+ module Windows
2
+ module Constants
3
+ SC_MANAGER_ALL_ACCESS = 0xF003F
4
+ SC_MANAGER_CREATE_SERVICE = 0x0002
5
+ SC_MANAGER_CONNECT = 0x0001
6
+ SC_MANAGER_ENUMERATE_SERVICE = 0x0004
7
+ SC_MANAGER_LOCK = 0x0008
8
+ SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020
9
+ SC_MANAGER_QUERY_LOCK_STATUS = 0x0010
10
+ SC_STATUS_PROCESS_INFO = 0
11
+ SC_ENUM_PROCESS_INFO = 0
12
+
13
+ # Service control action types
14
+ SC_ACTION_NONE = 0
15
+ SC_ACTION_RESTART = 1
16
+ SC_ACTION_REBOOT = 2
17
+ SC_ACTION_RUN_COMMAND = 3
18
+
19
+ # Service access rights
20
+ SERVICE_ALL_ACCESS = 0xF01FF
21
+ SERVICE_CHANGE_CONFIG = 0x0002
22
+ SERVICE_ENUMERATE_DEPENDENTS = 0x0008
23
+ SERVICE_INTERROGATE = 0x0080
24
+ SERVICE_PAUSE_CONTINUE = 0x0040
25
+ SERVICE_QUERY_CONFIG = 0x0001
26
+ SERVICE_QUERY_STATUS = 0x0004
27
+ SERVICE_START = 0x0010
28
+ SERVICE_STOP = 0x0020
29
+ SERVICE_USER_DEFINED_CONTROL = 0x0100
30
+
31
+ # Service types
32
+ SERVICE_KERNEL_DRIVER = 0x00000001
33
+ SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
34
+ SERVICE_ADAPTER = 0x00000004
35
+ SERVICE_RECOGNIZER_DRIVER = 0x00000008
36
+ SERVICE_WIN32_OWN_PROCESS = 0x00000010
37
+ SERVICE_WIN32_SHARE_PROCESS = 0x00000020
38
+ SERVICE_WIN32 = 0x00000030
39
+ SERVICE_INTERACTIVE_PROCESS = 0x00000100
40
+ SERVICE_DRIVER = 0x0000000B
41
+ SERVICE_TYPE_ALL = 0x0000013F
42
+
43
+ # Error control
44
+ SERVICE_ERROR_IGNORE = 0x00000000
45
+ SERVICE_ERROR_NORMAL = 0x00000001
46
+ SERVICE_ERROR_SEVERE = 0x00000002
47
+ SERVICE_ERROR_CRITICAL = 0x00000003
48
+
49
+ # Start types
50
+ SERVICE_BOOT_START = 0x00000000
51
+ SERVICE_SYSTEM_START = 0x00000001
52
+ SERVICE_AUTO_START = 0x00000002
53
+ SERVICE_DEMAND_START = 0x00000003
54
+ SERVICE_DISABLED = 0x00000004
55
+
56
+ # Service control
57
+
58
+ SERVICE_CONTROL_STOP = 0x00000001
59
+ SERVICE_CONTROL_PAUSE = 0x00000002
60
+ SERVICE_CONTROL_CONTINUE = 0x00000003
61
+ SERVICE_CONTROL_INTERROGATE = 0x00000004
62
+ SERVICE_CONTROL_SHUTDOWN = 0x00000005
63
+ SERVICE_CONTROL_PARAMCHANGE = 0x00000006
64
+ SERVICE_CONTROL_NETBINDADD = 0x00000007
65
+ SERVICE_CONTROL_NETBINDREMOVE = 0x00000008
66
+ SERVICE_CONTROL_NETBINDENABLE = 0x00000009
67
+ SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A
68
+ SERVICE_CONTROL_DEVICEEVENT = 0x0000000B
69
+ SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C
70
+ SERVICE_CONTROL_POWEREVENT = 0x0000000D
71
+ SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E
72
+ SERVICE_CONTROL_PRESHUTDOWN = 0x0000000F
73
+ SERVICE_CONTROL_TIMECHANGE = 0x00000010
74
+ SERVICE_CONTROL_TRIGGEREVENT = 0x00000020
75
+
76
+ # Service controls accepted
77
+
78
+ SERVICE_ACCEPT_STOP = 0x00000001
79
+ SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002
80
+ SERVICE_ACCEPT_SHUTDOWN = 0x00000004
81
+ SERVICE_ACCEPT_PARAMCHANGE = 0x00000008
82
+ SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010
83
+ SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
84
+ SERVICE_ACCEPT_POWEREVENT = 0x00000040
85
+ SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
86
+ SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100
87
+ SERVICE_ACCEPT_TIMECHANGE = 0x00000200
88
+ SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400
89
+
90
+ # Service states
91
+ SERVICE_ACTIVE = 0x00000001
92
+ SERVICE_INACTIVE = 0x00000002
93
+ SERVICE_STATE_ALL = 0x00000003
94
+
95
+ # Service current states
96
+ SERVICE_STOPPED = 0x00000001
97
+ SERVICE_START_PENDING = 0x00000002
98
+ SERVICE_STOP_PENDING = 0x00000003
99
+ SERVICE_RUNNING = 0x00000004
100
+ SERVICE_CONTINUE_PENDING = 0x00000005
101
+ SERVICE_PAUSE_PENDING = 0x00000006
102
+ SERVICE_PAUSED = 0x00000007
103
+
104
+ # Info levels
105
+ SERVICE_CONFIG_DESCRIPTION = 1
106
+ SERVICE_CONFIG_FAILURE_ACTIONS = 2
107
+ SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3
108
+ SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4
109
+ SERVICE_CONFIG_SERVICE_SID_INFO = 5
110
+ SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6
111
+ SERVICE_CONFIG_PRESHUTDOWN_INFO = 7
112
+
113
+ # Configuration
114
+ SERVICE_NO_CHANGE = 0xffffffff
115
+
116
+ # Misc
117
+
118
+ WAIT_OBJECT_0 = 0
119
+ WAIT_TIMEOUT = 0x00000102
120
+ INFINITE = 0xFFFFFFFF
121
+
122
+ IDLE_CONTROL_CODE = 0
123
+
124
+ DELETE = 0x00010000
125
+ FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
126
+ FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
127
+
128
+ NO_ERROR = 0
129
+
130
+ # Errors
131
+
132
+ ERROR_INSUFFICIENT_BUFFER = 122
133
+ ERROR_MORE_DATA = 234
134
+ ERROR_FILE_NOT_FOUND = 2
135
+ WAIT_FAILED = 0xFFFFFFFF
136
+ end
137
+ end
@@ -0,0 +1,63 @@
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module Functions
5
+ extend FFI::Library
6
+
7
+ typedef :ulong, :dword
8
+ typedef :uintptr_t, :handle
9
+ typedef :pointer, :ptr
10
+ typedef :string, :str
11
+
12
+ ffi_convention :stdcall
13
+
14
+ ffi_lib :kernel32
15
+
16
+ attach_function :CloseHandle, [:handle], :bool
17
+ attach_function :CreateEvent, :CreateEventA, [:ptr, :bool, :bool, :str], :handle
18
+ attach_function :CreateThread, [:ptr, :size_t, :ptr, :ptr, :dword, :ptr], :handle, :blocking => true
19
+ attach_function :EnterCriticalSection, [:ptr], :void
20
+ attach_function :FormatMessage, :FormatMessageA, [:ulong, :ptr, :ulong, :ulong, :str, :ulong, :ptr], :ulong
21
+ attach_function :InitializeCriticalSection, [:ptr], :void
22
+ attach_function :LeaveCriticalSection, [:ptr], :void
23
+ attach_function :SetEvent, [:handle], :bool
24
+ attach_function :WaitForSingleObject, [:handle, :dword], :dword, :blocking => true
25
+ attach_function :WaitForMultipleObjects, [:dword, :ptr, :bool, :dword], :dword
26
+
27
+ ffi_lib :advapi32
28
+
29
+ callback :handler_ex, [:ulong, :ulong, :ptr, :ptr], :void
30
+
31
+ attach_function :CloseServiceHandle, [:handle], :bool
32
+
33
+ attach_function :ChangeServiceConfig, :ChangeServiceConfigA,
34
+ [:handle, :dword, :dword, :dword, :str, :str, :ptr, :str, :str, :str, :str],
35
+ :bool
36
+
37
+ attach_function :ChangeServiceConfig2, :ChangeServiceConfig2A, [:handle, :dword, :ptr], :bool
38
+
39
+ attach_function :CreateService, :CreateServiceA,
40
+ [:handle, :string, :string, :dword, :dword, :dword, :dword,
41
+ :string, :string, :ptr, :pointer, :string, :string],
42
+ :handle
43
+
44
+ attach_function :ControlService, [:handle, :dword, :ptr], :bool
45
+ attach_function :DeleteService, [:handle], :bool
46
+
47
+ attach_function :EnumServicesStatusEx, :EnumServicesStatusExA,
48
+ [:handle, :int, :dword, :dword, :ptr, :dword, :ptr, :ptr, :ptr, :string],
49
+ :bool
50
+
51
+ attach_function :GetServiceDisplayName, :GetServiceDisplayNameA, [:handle, :string, :ptr, :ptr], :bool
52
+ attach_function :GetServiceKeyName, :GetServiceKeyNameA, [:handle, :string, :ptr, :ptr], :bool
53
+ attach_function :OpenSCManager, :OpenSCManagerA, [:ptr, :ptr, :dword], :handle
54
+ attach_function :OpenService, :OpenServiceA, [:handle, :string, :dword], :handle
55
+ attach_function :QueryServiceConfig, :QueryServiceConfigA, [:handle, :ptr, :dword, :ptr], :bool
56
+ attach_function :QueryServiceConfig2, :QueryServiceConfig2A, [:handle, :dword, :ptr, :dword, :ptr], :bool
57
+ attach_function :QueryServiceStatusEx, [:handle, :int, :ptr, :dword, :ptr], :bool
58
+ attach_function :RegisterServiceCtrlHandlerEx, :RegisterServiceCtrlHandlerExA, [:str, :handler_ex, :ptr], :handle
59
+ attach_function :SetServiceStatus, [:handle, :ptr], :bool
60
+ attach_function :StartService, :StartServiceA, [:handle, :dword, :ptr], :bool
61
+ attach_function :StartServiceCtrlDispatcher, :StartServiceCtrlDispatcherA, [:ptr], :bool, :blocking => true
62
+ end
63
+ end
@@ -0,0 +1,41 @@
1
+ require 'ffi'
2
+
3
+ class FFI::Pointer
4
+ def read_array_of_null_separated_strings
5
+ elements = []
6
+ loc = self
7
+
8
+ while element = loc.read_string
9
+ break if element.nil? || element == ""
10
+ elements << element
11
+ loc += element.size + 1
12
+ end
13
+
14
+ elements
15
+ end
16
+ end
17
+
18
+ module FFI
19
+ extend FFI::Library
20
+
21
+ ffi_lib :kernel32
22
+
23
+ attach_function :FormatMessage, :FormatMessageA,
24
+ [:ulong, :pointer, :ulong, :ulong, :pointer, :ulong, :pointer], :ulong
25
+
26
+ def win_error(function, err=FFI.errno)
27
+ flags = 0x00001000 | 0x00000200
28
+ buf = FFI::MemoryPointer.new(:char, 1024)
29
+
30
+ FormatMessage(flags, nil, err , 0x0409, buf, 1024, nil)
31
+
32
+ function + ': ' + buf.read_string.strip
33
+ end
34
+
35
+ def raise_windows_error(function, err=FFI.errno)
36
+ raise SystemCallError.new(win_error(function, err), err)
37
+ end
38
+
39
+ module_function :win_error
40
+ module_function :raise_windows_error
41
+ end
@@ -0,0 +1,96 @@
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module Structs
5
+ extend FFI::Library
6
+
7
+ typedef :ulong, :dword
8
+
9
+ class SERVICE_STATUS < FFI::Struct
10
+ layout(
11
+ :dwServiceType, :ulong,
12
+ :dwCurrentState, :ulong,
13
+ :dwControlsAccepted, :ulong,
14
+ :dwWin32ExitCode, :ulong,
15
+ :dwServiceSpecificExitCode, :ulong,
16
+ :dwCheckPoint, :ulong,
17
+ :dwWaitHint, :ulong
18
+ )
19
+ end
20
+
21
+ class SERVICE_STATUS_PROCESS < FFI::Struct
22
+ layout(
23
+ :dwServiceType, :dword,
24
+ :dwCurrentState, :dword,
25
+ :dwControlsAccepted, :dword,
26
+ :dwWin32ExitCode, :dword,
27
+ :dwServiceSpecificExitCode, :dword,
28
+ :dwCheckPoint, :dword,
29
+ :dwWaitHint, :dword,
30
+ :dwProcessId, :dword,
31
+ :dwServiceFlags, :dword
32
+ )
33
+ end
34
+
35
+ class SERVICE_DESCRIPTION < FFI::Struct
36
+ layout(:lpDescription, :pointer)
37
+ end
38
+
39
+ class QUERY_SERVICE_CONFIG < FFI::Struct
40
+ layout(
41
+ :dwServiceType, :dword,
42
+ :dwStartType, :dword,
43
+ :dwErrorControl, :dword,
44
+ :lpBinaryPathName, :pointer,
45
+ :lpLoadOrderGroup, :pointer,
46
+ :dwTagId, :dword,
47
+ :lpDependencies, :pointer,
48
+ :lpServiceStartName, :pointer,
49
+ :lpDisplayName, :pointer
50
+ )
51
+ end
52
+
53
+ class SERVICE_STATUS_PROCESS < FFI::Struct
54
+ layout(
55
+ :dwServiceType, :dword,
56
+ :dwCurrentState, :dword,
57
+ :dwControlsAccepted, :dword,
58
+ :dwWin32ExitCode, :dword,
59
+ :dwServiceSpecificExitCode, :dword,
60
+ :dwCheckPoint, :dword,
61
+ :dwWaitHint, :dword,
62
+ :dwProcessId, :dword,
63
+ :dwServiceFlags, :dword
64
+ )
65
+ end
66
+
67
+ class ENUM_SERVICE_STATUS_PROCESS < FFI::Struct
68
+ layout(
69
+ :lpServiceName, :pointer,
70
+ :lpDisplayName, :pointer,
71
+ :ServiceStatusProcess, SERVICE_STATUS_PROCESS
72
+ )
73
+ end
74
+
75
+ class SC_ACTION < FFI::Struct
76
+ layout(:Type, :int, :Delay, :dword)
77
+ end
78
+
79
+ class SERVICE_FAILURE_ACTIONS < FFI::Struct
80
+ layout(
81
+ :dwResetPeriod, :dword,
82
+ :lpRebootMsg, :pointer,
83
+ :lpCommand, :pointer,
84
+ :cActions, :dword,
85
+ :lpsaActions, :pointer # Array of SC_ACTION structs
86
+ )
87
+ end
88
+
89
+ class SERVICE_TABLE_ENTRY < FFI::Struct
90
+ layout(
91
+ :lpServiceName, :pointer,
92
+ :lpServiceProc, :pointer
93
+ )
94
+ end
95
+ end
96
+ end
@@ -7,22 +7,19 @@
7
7
  # These tests are rather limited, since the acid test is to install
8
8
  # your daemon as a service and see how it behaves.
9
9
  #########################################################################
10
- require 'rubygems'
11
- gem 'test-unit'
12
-
10
+ require 'test-unit'
13
11
  require 'win32/daemon'
14
- require 'test/unit'
15
12
  include Win32
16
13
 
17
14
  class TC_Daemon < Test::Unit::TestCase
18
15
  def setup
19
16
  @daemon = Daemon.new
20
17
  end
21
-
18
+
22
19
  test "version number is set properly" do
23
- assert_equal('0.7.2', Daemon::VERSION)
20
+ assert_equal('0.8.0', Daemon::VERSION)
24
21
  end
25
-
22
+
26
23
  test "constructor basic functionality" do
27
24
  assert_respond_to(Daemon, :new)
28
25
  assert_nothing_raised{ Daemon.new }
@@ -31,19 +28,19 @@ class TC_Daemon < Test::Unit::TestCase
31
28
  test "constructor does not accept any arguments" do
32
29
  assert_raises(ArgumentError){ Daemon.new(1) }
33
30
  end
34
-
31
+
35
32
  test "mainloop basic functionality" do
36
33
  assert_respond_to(@daemon, :mainloop)
37
34
  end
38
-
35
+
39
36
  test "state basic functionality" do
40
37
  assert_respond_to(@daemon, :state)
41
38
  end
42
-
39
+
43
40
  test "is_running basic functionality" do
44
41
  assert_respond_to(@daemon, :running?)
45
42
  end
46
-
43
+
47
44
  test "expected constants are defined" do
48
45
  assert_not_nil(Daemon::CONTINUE_PENDING)
49
46
  assert_not_nil(Daemon::PAUSE_PENDING)
@@ -52,9 +49,9 @@ class TC_Daemon < Test::Unit::TestCase
52
49
  assert_not_nil(Daemon::START_PENDING)
53
50
  assert_not_nil(Daemon::STOP_PENDING)
54
51
  assert_not_nil(Daemon::STOPPED)
55
- assert_not_nil(Daemon::IDLE)
52
+ assert_not_nil(Daemon::IDLE)
56
53
  end
57
-
54
+
58
55
  def teardown
59
56
  @daemon = nil
60
57
  end
@@ -1,14 +1,12 @@
1
1
  ##########################################################################
2
2
  # test_win32_service.rb
3
- #
3
+ #
4
4
  # Tests for the Win32::Service class.
5
5
  ##########################################################################
6
- require 'rubygems'
7
- gem 'test-unit'
8
-
6
+ require 'test-unit'
9
7
  require 'win32/service'
8
+ require 'win32/security'
10
9
  require 'socket'
11
- require 'test/unit'
12
10
 
13
11
  class TC_Win32_Service < Test::Unit::TestCase
14
12
  def self.startup
@@ -21,6 +19,7 @@ class TC_Win32_Service < Test::Unit::TestCase
21
19
  @service_name = 'stisvc'
22
20
  @service_stat = nil
23
21
  @services = []
22
+ @elevated = Win32::Security.elevated_security?
24
23
  end
25
24
 
26
25
  def start_service(service)
@@ -42,7 +41,7 @@ class TC_Win32_Service < Test::Unit::TestCase
42
41
  end
43
42
  wait_for_status('stopped')
44
43
  end
45
-
44
+
46
45
  # Helper method that waits for a status to change its state since state
47
46
  # changes aren't usually instantaneous.
48
47
  def wait_for_status(status)
@@ -50,28 +49,28 @@ class TC_Win32_Service < Test::Unit::TestCase
50
49
  end
51
50
 
52
51
  test "version number is expected value" do
53
- assert_equal('0.7.2', Win32::Service::VERSION)
52
+ assert_equal('0.8.0', Win32::Service::VERSION)
54
53
  end
55
-
54
+
56
55
  test "services basic functionality" do
57
56
  assert_respond_to(Win32::Service, :services)
58
57
  assert_nothing_raised{ Win32::Service.services }
59
58
  assert_nothing_raised{ Win32::Service.services(nil) }
60
59
  assert_nothing_raised{ Win32::Service.services(nil, 'network') }
61
60
  end
62
-
61
+
63
62
  test "services method returns an array without a block" do
64
63
  assert_nothing_raised{ @services = Win32::Service.services }
65
64
  assert_kind_of(Array, @services)
66
65
  assert_kind_of(Struct::ServiceInfo, @services[0])
67
66
  end
68
-
67
+
69
68
  test "services method yields service objects when a block is provided" do
70
69
  assert_nothing_raised{ Win32::Service.services{ |s| @services << s } }
71
70
  assert_kind_of(Array, @services)
72
- assert_kind_of(Struct::ServiceInfo, @services[0])
71
+ assert_kind_of(Struct::ServiceInfo, @services[0])
73
72
  end
74
-
73
+
75
74
  test "the host argument must be a string or an error is raised" do
76
75
  assert_raise(TypeError){ Win32::Service.services(1) }
77
76
  end
@@ -85,29 +84,29 @@ class TC_Win32_Service < Test::Unit::TestCase
85
84
  end
86
85
 
87
86
  test "a valid hostname must be provided or an error is raised" do
88
- assert_raise(Win32::Service::Error){ Win32::Service.services('bogus') }
89
- end
90
-
87
+ assert_raise(SystemCallError){ Win32::Service.services('bogus') }
88
+ end
89
+
91
90
  test "delete method basic functionality" do
92
91
  assert_respond_to(Win32::Service, :delete)
93
92
  end
94
-
93
+
95
94
  test "a service name must be provided to the delete method" do
96
95
  assert_raise(ArgumentError){ Win32::Service.delete }
97
96
  end
98
97
 
99
98
  test "delete method raises an error if a bogus service name is provided" do
100
- assert_raise(Win32::Service::Error){ Win32::Service.delete('bogus') }
99
+ assert_raise(SystemCallError){ Win32::Service.delete('bogus') }
101
100
  end
102
101
 
103
102
  test "delete method raises an error if a bogus host name is provided" do
104
- assert_raise(Win32::Service::Error){ Win32::Service.delete('bogus', 'bogus') }
103
+ assert_raise(SystemCallError){ Win32::Service.delete('bogus', 'bogus') }
105
104
  end
106
105
 
107
106
  test "delete method only accepts up to two arguments" do
108
107
  assert_raise(ArgumentError){ Win32::Service.delete('x', 'y', 'z') }
109
108
  end
110
-
109
+
111
110
  test "pause basic functionality" do
112
111
  assert_respond_to(Win32::Service, :pause)
113
112
  end
@@ -117,6 +116,7 @@ class TC_Win32_Service < Test::Unit::TestCase
117
116
  end
118
117
 
119
118
  test "pause and resume work as expected" do
119
+ omit_unless(@elevated, "Skipped unless run with admin privileges")
120
120
  start_service(@service_name)
121
121
 
122
122
  assert_nothing_raised{ Win32::Service.pause(@service_name) }
@@ -129,47 +129,47 @@ class TC_Win32_Service < Test::Unit::TestCase
129
129
  test "pausing an already paused service is harmless" do
130
130
  start_service(@service_name)
131
131
 
132
- assert_nothing_raised{ Win32::Service.pause(@service_name) }
132
+ assert_nothing_raised{ Win32::Service.pause(@service_name) }
133
133
  wait_for_status('paused')
134
- assert_nothing_raised{ Win32::Service.pause(@service_name) }
134
+ assert_nothing_raised{ Win32::Service.pause(@service_name) }
135
135
  end
136
-
136
+
137
137
  test "pause requires a service name as an argument" do
138
138
  assert_raise(ArgumentError){ Win32::Service.pause }
139
139
  end
140
140
 
141
141
  test "pausing an unrecognized service name raises an error" do
142
- assert_raise(Win32::Service::Error){ Win32::Service.pause('bogus') }
142
+ assert_raise(SystemCallError){ Win32::Service.pause('bogus') }
143
143
  end
144
144
 
145
145
  test "pausing a service on an unrecognized host raises an error" do
146
- assert_raise(Win32::Service::Error){ Win32::Service.pause('W32Time', 'bogus') }
146
+ assert_raise(SystemCallError){ Win32::Service.pause('W32Time', 'bogus') }
147
147
  end
148
148
 
149
149
  test "pause method accepts a maximum of two arguments" do
150
150
  assert_raise(ArgumentError){ Win32::Service.pause('x', 'y', 'z') }
151
151
  end
152
-
152
+
153
153
  test "resume method requires a service name" do
154
154
  assert_raise(ArgumentError){ Win32::Service.resume }
155
155
  end
156
156
 
157
157
  test "resume method with an unrecognized service name raises an error" do
158
- assert_raise(Win32::Service::Error){ Win32::Service.resume('bogus') }
158
+ assert_raise(SystemCallError){ Win32::Service.resume('bogus') }
159
159
  end
160
160
 
161
161
  test "resume method with an unrecognized host name raises an error" do
162
- assert_raise(Win32::Service::Error){ Win32::Service.resume('W32Time', 'bogus') }
162
+ assert_raise(SystemCallError){ Win32::Service.resume('W32Time', 'bogus') }
163
163
  end
164
164
 
165
165
  test "resume method accepts a maximum of two arguments" do
166
166
  assert_raise(ArgumentError){ Win32::Service.resume('W32Time', @@host, true) }
167
- end
167
+ end
168
168
 
169
169
  test "stop method basic functionality" do
170
170
  assert_respond_to(Win32::Service, :stop)
171
171
  end
172
-
172
+
173
173
  test "start method basic functionality" do
174
174
  assert_respond_to(Win32::Service, :start)
175
175
  end
@@ -189,41 +189,41 @@ class TC_Win32_Service < Test::Unit::TestCase
189
189
 
190
190
  assert_nothing_raised{ Win32::Service.stop(@service_name) }
191
191
  wait_for_status('stopped')
192
- assert_raise(Win32::Service::Error){ Win32::Service.stop(@service_name) }
192
+ assert_raise(SystemCallError){ Win32::Service.stop(@service_name) }
193
193
 
194
194
  assert_nothing_raised{ Win32::Service.start(@service_name) }
195
195
  end
196
-
196
+
197
197
  test "stop method requires a service name" do
198
198
  assert_raise(ArgumentError){ Win32::Service.stop }
199
199
  end
200
200
 
201
201
  test "stop method raises an error if the service name is unrecognized" do
202
- assert_raise(Win32::Service::Error){ Win32::Service.stop('bogus') }
202
+ assert_raise(SystemCallError){ Win32::Service.stop('bogus') }
203
203
  end
204
204
 
205
205
  test "stop method raises an error if the host is unrecognized" do
206
- assert_raise(Win32::Service::Error){ Win32::Service.stop('W32Time', 'bogus') }
206
+ assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
207
207
  end
208
208
 
209
209
  test "stop metho accepts a maximum of two arguments" do
210
210
  assert_raise(ArgumentError){ Win32::Service.stop('W32Time', @@host, true) }
211
211
  end
212
-
212
+
213
213
  test "start method requires a service name" do
214
214
  assert_raise(ArgumentError){ Win32::Service.start }
215
215
  end
216
216
 
217
217
  test "attempting to start a running service raises an error" do
218
- assert_raise(Win32::Service::Error){ Win32::Service.start(@service_name) }
218
+ assert_raise(SystemCallError){ Win32::Service.start(@service_name) }
219
219
  end
220
220
 
221
221
  test "attempting to start an unrecognized service raises an error" do
222
- assert_raise(Win32::Service::Error){ Win32::Service.start('bogus') }
222
+ assert_raise(SystemCallError){ Win32::Service.start('bogus') }
223
223
  end
224
224
 
225
225
  test "attempting to start a service on an unknown host raises an error" do
226
- assert_raise(Win32::Service::Error){ Win32::Service.start('bogus', 'bogus') }
226
+ assert_raise(SystemCallError){ Win32::Service.start('bogus', 'bogus') }
227
227
  end
228
228
 
229
229
  test "stop requires at least one argument" do
@@ -231,11 +231,11 @@ class TC_Win32_Service < Test::Unit::TestCase
231
231
  end
232
232
 
233
233
  test "stop raises an error with an unrecognized service name" do
234
- assert_raise(Win32::Service::Error){ Win32::Service.stop('bogus') }
234
+ assert_raise(SystemCallError){ Win32::Service.stop('bogus') }
235
235
  end
236
236
 
237
237
  test "stop raises an error with an unrecognized host" do
238
- assert_raise(Win32::Service::Error){ Win32::Service.stop('W32Time', 'bogus') }
238
+ assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
239
239
  end
240
240
 
241
241
  test "stop accepts a maximum of 2 arguments" do
@@ -268,11 +268,11 @@ class TC_Win32_Service < Test::Unit::TestCase
268
268
  end
269
269
 
270
270
  test "get_service_name raises an error if a bogus service name is provided" do
271
- assert_raise(Win32::Service::Error){ Win32::Service.get_service_name('bogus') }
271
+ assert_raise(SystemCallError){ Win32::Service.get_service_name('bogus') }
272
272
  end
273
273
 
274
274
  test "get_service_name raises an error if a bogus host is provided" do
275
- assert_raise(Win32::Service::Error){ Win32::Service.get_service_name('foo', 'bogus') }
275
+ assert_raise(SystemCallError){ Win32::Service.get_service_name('foo', 'bogus') }
276
276
  end
277
277
 
278
278
  test "get_service_name accepts a maximum of two arguments" do
@@ -299,11 +299,11 @@ class TC_Win32_Service < Test::Unit::TestCase
299
299
  end
300
300
 
301
301
  test "get_display_name raises an error if the service does not exist" do
302
- assert_raise(Win32::Service::Error){ Win32::Service.get_display_name('bogus') }
302
+ assert_raise(SystemCallError){ Win32::Service.get_display_name('bogus') }
303
303
  end
304
304
 
305
305
  test "get_display_name raises an error if a bad host name is provided" do
306
- assert_raise(Win32::Service::Error){ Win32::Service.get_display_name('W32Time', 'bogus') }
306
+ assert_raise(SystemCallError){ Win32::Service.get_display_name('W32Time', 'bogus') }
307
307
  end
308
308
 
309
309
  test "get_display_name takes a maximum of two arguments" do
@@ -312,6 +312,7 @@ class TC_Win32_Service < Test::Unit::TestCase
312
312
 
313
313
  test "exists method basic functionality" do
314
314
  assert_respond_to(Win32::Service, :exists?)
315
+ assert_boolean(Win32::Service.exists?('W32Time'))
315
316
  assert_nothing_raised{ Win32::Service.exists?('W32Time') }
316
317
  end
317
318
 
@@ -325,13 +326,17 @@ class TC_Win32_Service < Test::Unit::TestCase
325
326
  end
326
327
 
327
328
  test "exists method raises an error if a bogus host is passed" do
328
- assert_raises(Win32::Service::Error){Win32::Service.exists?('foo', 'bogushost') }
329
+ assert_raises(SystemCallError){
330
+ Win32::Service.exists?('foo', 'bogushost')
331
+ }
329
332
  end
330
333
 
331
334
  test "exists method only accepts up to two arguments" do
332
- assert_raises(ArgumentError){ Win32::Service.exists?('foo', 'bar', 'baz') }
335
+ assert_raises(ArgumentError){
336
+ Win32::Service.exists?('foo', 'bar', 'baz')
337
+ }
333
338
  end
334
-
339
+
335
340
  test "scm security constants are defined" do
336
341
  assert_not_nil(Win32::Service::MANAGER_ALL_ACCESS)
337
342
  assert_not_nil(Win32::Service::MANAGER_CREATE_SERVICE)
@@ -384,14 +389,15 @@ class TC_Win32_Service < Test::Unit::TestCase
384
389
  assert_not_nil(Win32::Service::RUNNING)
385
390
  assert_not_nil(Win32::Service::START_PENDING)
386
391
  assert_not_nil(Win32::Service::STOP_PENDING)
387
- assert_not_nil(Win32::Service::STOPPED)
392
+ assert_not_nil(Win32::Service::STOPPED)
388
393
  end
389
-
394
+
390
395
  def teardown
391
396
  @display_name = nil
392
397
  @service_name = nil
393
398
  @service_stat = nil
394
399
  @services = nil
400
+ @elevated = nil
395
401
  end
396
402
 
397
403
  def self.shutdown