win32-service 2.2.0 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/win32/daemon.rb +54 -50
- data/lib/win32/service.rb +221 -221
- data/lib/win32/windows/functions.rb +27 -27
- data/lib/win32/windows/structs.rb +1 -1
- data/lib/win32/windows/version.rb +1 -1
- data/lib/win32-daemon.rb +1 -1
- data/lib/win32-service.rb +1 -1
- metadata +3 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 746b781ce8ab92f9ef2f38854781e593281687956b171bd4aa57054e02b68648
|
4
|
+
data.tar.gz: 55ac6d06feb8f47751ffee8edee887420001d4b11ba5e5cce16daae343c80e1b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cd8d485dae8159f1d0d788baa22c30fb5b98ab71623ef935c7b27535c100e6fa4b33cc59aa9617c313c3d33a637ab1dc8034aac236f5231e0fb09d2487fa308
|
7
|
+
data.tar.gz: e8410fc1cd05028d99b6f3c1822e635e85e50eb3b08f48e291fb20cfa06ad1c98bce740fc25af51eea7aa1a18b990f78727be0eed7ddc648d4f4b3875ac5c6fa
|
data/lib/win32/daemon.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require_relative
|
2
|
-
require_relative
|
3
|
-
require_relative
|
4
|
-
require_relative
|
1
|
+
require_relative "windows/constants"
|
2
|
+
require_relative "windows/structs"
|
3
|
+
require_relative "windows/functions"
|
4
|
+
require_relative "windows/version"
|
5
5
|
|
6
6
|
# The Win32 module serves as a namespace only.
|
7
7
|
module Win32
|
@@ -18,8 +18,6 @@ module Win32
|
|
18
18
|
# The version of this library
|
19
19
|
VERSION = Win32::Service::VERSION
|
20
20
|
|
21
|
-
private
|
22
|
-
|
23
21
|
# Service is not running
|
24
22
|
STOPPED = SERVICE_STOPPED
|
25
23
|
|
@@ -73,16 +71,16 @@ module Win32
|
|
73
71
|
IDLE = 0
|
74
72
|
|
75
73
|
# Wraps SetServiceStatus.
|
76
|
-
SetTheServiceStatus = Proc.new do |dwCurrentState, dwWin32ExitCode,dwCheckPoint,
|
77
|
-
ss = SERVICE_STATUS.new
|
74
|
+
SetTheServiceStatus = Proc.new do |dwCurrentState, dwWin32ExitCode, dwCheckPoint, dwWaitHint|
|
75
|
+
ss = SERVICE_STATUS.new # Current status of the service.
|
78
76
|
|
79
77
|
# Disable control requests until the service is started.
|
80
78
|
if dwCurrentState == SERVICE_START_PENDING
|
81
79
|
ss[:dwControlsAccepted] = 0
|
82
80
|
else
|
83
81
|
ss[:dwControlsAccepted] =
|
84
|
-
SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN|
|
85
|
-
SERVICE_ACCEPT_PAUSE_CONTINUE|SERVICE_ACCEPT_PARAMCHANGE
|
82
|
+
SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN |
|
83
|
+
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_PARAMCHANGE
|
86
84
|
end
|
87
85
|
|
88
86
|
# Initialize ss structure.
|
@@ -96,7 +94,7 @@ module Win32
|
|
96
94
|
@@dwServiceState = dwCurrentState
|
97
95
|
|
98
96
|
# Send status of the service to the Service Controller.
|
99
|
-
|
97
|
+
unless SetServiceStatus(@@ssh, ss)
|
100
98
|
SetEvent(@@hStopEvent)
|
101
99
|
end
|
102
100
|
end
|
@@ -104,8 +102,8 @@ module Win32
|
|
104
102
|
ERROR_CALL_NOT_IMPLEMENTED = 0x78
|
105
103
|
|
106
104
|
# Handles control signals from the service control manager.
|
107
|
-
Service_Ctrl_ex = Proc.new do |dwCtrlCode,dwEventType,lpEventData,lpContext|
|
108
|
-
@@waiting_control_code = dwCtrlCode
|
105
|
+
Service_Ctrl_ex = Proc.new do |dwCtrlCode, dwEventType, lpEventData, lpContext|
|
106
|
+
@@waiting_control_code = dwCtrlCode
|
109
107
|
return_value = NO_ERROR
|
110
108
|
|
111
109
|
begin
|
@@ -120,8 +118,8 @@ module Win32
|
|
120
118
|
dwState = SERVICE_PAUSED
|
121
119
|
when SERVICE_CONTROL_CONTINUE
|
122
120
|
dwState = SERVICE_RUNNING
|
123
|
-
#else
|
124
|
-
|
121
|
+
# else
|
122
|
+
# TODO: Handle other control codes? Retain the current state?
|
125
123
|
end
|
126
124
|
|
127
125
|
# Set the status of the service except on interrogation.
|
@@ -143,18 +141,18 @@ module Win32
|
|
143
141
|
end
|
144
142
|
|
145
143
|
# Called by the service control manager after the call to StartServiceCtrlDispatcher.
|
146
|
-
Service_Main = FFI::Function.new(:void,
|
144
|
+
Service_Main = FFI::Function.new(:void, %i{ulong pointer}, blocking: false) do |dwArgc, lpszArgv|
|
147
145
|
begin
|
148
146
|
# Obtain the name of the service.
|
149
|
-
if lpszArgv.address!=0
|
150
|
-
argv = lpszArgv.get_array_of_string(0,dwArgc)
|
147
|
+
if lpszArgv.address != 0
|
148
|
+
argv = lpszArgv.get_array_of_string(0, dwArgc)
|
151
149
|
lpszServiceName = argv[0]
|
152
150
|
else
|
153
|
-
lpszServiceName =
|
151
|
+
lpszServiceName = ""
|
154
152
|
end
|
155
153
|
|
156
154
|
# Args passed to Service.start
|
157
|
-
if
|
155
|
+
if dwArgc > 1
|
158
156
|
@@Argv = argv[1..-1]
|
159
157
|
else
|
160
158
|
@@Argv = nil
|
@@ -176,11 +174,11 @@ module Win32
|
|
176
174
|
SetEvent(@@hStartEvent)
|
177
175
|
|
178
176
|
# Main loop for the service.
|
179
|
-
while
|
177
|
+
while WaitForSingleObject(@@hStopEvent, 1000) != WAIT_OBJECT_0
|
180
178
|
end
|
181
179
|
|
182
180
|
# Main loop for the service.
|
183
|
-
while
|
181
|
+
while WaitForSingleObject(@@hStopCompletedEvent, 1000) != WAIT_OBJECT_0
|
184
182
|
end
|
185
183
|
ensure
|
186
184
|
# Stop the service.
|
@@ -188,11 +186,11 @@ module Win32
|
|
188
186
|
end
|
189
187
|
end
|
190
188
|
|
191
|
-
ThreadProc = FFI::Function.new(:ulong,[:pointer]) do |lpParameter|
|
189
|
+
ThreadProc = FFI::Function.new(:ulong, [:pointer]) do |lpParameter|
|
192
190
|
ste = FFI::MemoryPointer.new(SERVICE_TABLE_ENTRY, 2)
|
193
191
|
|
194
192
|
s = SERVICE_TABLE_ENTRY.new(ste[0])
|
195
|
-
s[:lpServiceName] = FFI::MemoryPointer.from_string(
|
193
|
+
s[:lpServiceName] = FFI::MemoryPointer.from_string("")
|
196
194
|
s[:lpServiceProc] = lpParameter
|
197
195
|
|
198
196
|
s = SERVICE_TABLE_ENTRY.new(ste[1])
|
@@ -200,19 +198,17 @@ module Win32
|
|
200
198
|
s[:lpServiceProc] = nil
|
201
199
|
|
202
200
|
# No service to step, no service handle, no ruby exceptions, just terminate the thread..
|
203
|
-
|
201
|
+
unless StartServiceCtrlDispatcher(ste)
|
204
202
|
return 1
|
205
203
|
end
|
206
204
|
|
207
205
|
return 0
|
208
206
|
end
|
209
207
|
|
210
|
-
public
|
211
|
-
|
212
208
|
# This is a shortcut for Daemon.new + Daemon#mainloop.
|
213
209
|
#
|
214
210
|
def self.mainloop
|
215
|
-
|
211
|
+
new.mainloop
|
216
212
|
end
|
217
213
|
|
218
214
|
# This is the method that actually puts your code into a loop and allows it
|
@@ -225,9 +221,9 @@ module Win32
|
|
225
221
|
|
226
222
|
# Redirect STDIN, STDOUT and STDERR to the NUL device if they're still
|
227
223
|
# associated with a tty. This helps newbs avoid Errno::EBADF errors.
|
228
|
-
STDIN.reopen(
|
229
|
-
STDOUT.reopen(
|
230
|
-
STDERR.reopen(
|
224
|
+
STDIN.reopen("NUL") if STDIN.isatty
|
225
|
+
STDOUT.reopen("NUL") if STDOUT.isatty
|
226
|
+
STDERR.reopen("NUL") if STDERR.isatty
|
231
227
|
|
232
228
|
# Calling init here so that init failures never even tries to start the
|
233
229
|
# service. Of course that means that init methods must be very quick
|
@@ -235,44 +231,44 @@ module Win32
|
|
235
231
|
# init's running.
|
236
232
|
#
|
237
233
|
# TODO: Fix?
|
238
|
-
service_init
|
234
|
+
service_init if respond_to?("service_init")
|
239
235
|
|
240
236
|
# Create the event to signal the service to start.
|
241
237
|
@@hStartEvent = CreateEvent(nil, 1, 0, nil)
|
242
238
|
|
243
239
|
if @@hStartEvent == 0
|
244
|
-
raise SystemCallError.new(
|
240
|
+
raise SystemCallError.new("CreateEvent", FFI.errno)
|
245
241
|
end
|
246
242
|
|
247
243
|
# Create the event to signal the service to stop.
|
248
244
|
@@hStopEvent = CreateEvent(nil, 1, 0, nil)
|
249
245
|
|
250
246
|
if @@hStopEvent == 0
|
251
|
-
raise SystemCallError.new(
|
247
|
+
raise SystemCallError.new("CreateEvent", FFI.errno)
|
252
248
|
end
|
253
249
|
|
254
250
|
# Create the event to signal the service that stop has completed
|
255
251
|
@@hStopCompletedEvent = CreateEvent(nil, 1, 0, nil)
|
256
252
|
|
257
253
|
if @@hStopCompletedEvent == 0
|
258
|
-
raise SystemCallError.new(
|
254
|
+
raise SystemCallError.new("CreateEvent", FFI.errno)
|
259
255
|
end
|
260
256
|
|
261
257
|
hThread = CreateThread(nil, 0, ThreadProc, Service_Main, 0, nil)
|
262
258
|
|
263
259
|
if hThread == 0
|
264
|
-
raise SystemCallError.new(
|
260
|
+
raise SystemCallError.new("CreateThread", FFI.errno)
|
265
261
|
end
|
266
262
|
|
267
263
|
events = FFI::MemoryPointer.new(:pointer, 2)
|
268
264
|
events.put_pointer(0, FFI::Pointer.new(hThread))
|
269
265
|
events.put_pointer(FFI::Pointer.size, FFI::Pointer.new(@@hStartEvent))
|
270
266
|
|
271
|
-
while (
|
267
|
+
while (index = WaitForMultipleObjects(2, events, 0, 1000)) == WAIT_TIMEOUT
|
272
268
|
end
|
273
269
|
|
274
270
|
if index == WAIT_FAILED
|
275
|
-
raise SystemCallError.new(
|
271
|
+
raise SystemCallError.new("WaitForMultipleObjects", FFI.errno)
|
276
272
|
end
|
277
273
|
|
278
274
|
# The thread exited, so the show is off.
|
@@ -282,38 +278,46 @@ module Win32
|
|
282
278
|
|
283
279
|
thr = Thread.new do
|
284
280
|
begin
|
285
|
-
while
|
281
|
+
while WaitForSingleObject(@@hStopEvent, 1000) == WAIT_TIMEOUT
|
286
282
|
# Check to see if anything interesting has been signaled
|
287
283
|
case @@waiting_control_code
|
288
284
|
when SERVICE_CONTROL_PAUSE
|
289
|
-
service_pause
|
285
|
+
service_pause if respond_to?("service_pause")
|
290
286
|
when SERVICE_CONTROL_CONTINUE
|
291
|
-
service_resume
|
287
|
+
service_resume if respond_to?("service_resume")
|
292
288
|
when SERVICE_CONTROL_INTERROGATE
|
293
|
-
service_interrogate
|
289
|
+
service_interrogate if respond_to?("service_interrogate")
|
294
290
|
when SERVICE_CONTROL_SHUTDOWN
|
295
|
-
service_shutdown
|
291
|
+
service_shutdown if respond_to?("service_shutdown")
|
296
292
|
when SERVICE_CONTROL_PARAMCHANGE
|
297
|
-
service_paramchange
|
293
|
+
service_paramchange if respond_to?("service_paramchange")
|
298
294
|
when SERVICE_CONTROL_NETBINDADD
|
299
|
-
service_netbindadd
|
295
|
+
service_netbindadd if respond_to?("service_netbindadd")
|
300
296
|
when SERVICE_CONTROL_NETBINDREMOVE
|
301
|
-
service_netbindremove
|
297
|
+
service_netbindremove if respond_to?("service_netbindremove")
|
302
298
|
when SERVICE_CONTROL_NETBINDENABLE
|
303
|
-
service_netbindenable
|
299
|
+
service_netbindenable if respond_to?("service_netbindenable")
|
304
300
|
when SERVICE_CONTROL_NETBINDDISABLE
|
305
|
-
service_netbinddisable
|
301
|
+
service_netbinddisable if respond_to?("service_netbinddisable")
|
306
302
|
end
|
303
|
+
|
304
|
+
# handle user defined control codes
|
305
|
+
if @@waiting_control_code >= 128 && @@waiting_control_code <= 255
|
306
|
+
if respond_to?("service_user_defined_control")
|
307
|
+
service_user_defined_control(@@waiting_control_code)
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
307
311
|
@@waiting_control_code = IDLE_CONTROL_CODE
|
308
312
|
end
|
309
313
|
|
310
|
-
service_stop
|
314
|
+
service_stop if respond_to?("service_stop")
|
311
315
|
ensure
|
312
316
|
SetEvent(@@hStopCompletedEvent)
|
313
317
|
end
|
314
318
|
end
|
315
319
|
|
316
|
-
if respond_to?(
|
320
|
+
if respond_to?("service_main")
|
317
321
|
service_main(*@@Argv)
|
318
322
|
end
|
319
323
|
|