win32-service 2.2.0 → 2.3.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.
- 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
|
|