win32-service 2.2.0 → 2.4.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.
- checksums.yaml +4 -4
- data/lib/win32/daemon.rb +97 -93
- data/lib/win32/service.rb +226 -239
- data/lib/win32/windows/functions.rb +28 -28
- 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 +8 -22
data/lib/win32/service.rb
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
require
|
|
2
|
-
require_relative
|
|
3
|
-
require_relative
|
|
4
|
-
require_relative
|
|
5
|
-
require_relative
|
|
1
|
+
require "ffi/win32/extensions"
|
|
2
|
+
require_relative "windows/version"
|
|
3
|
+
require_relative "windows/constants"
|
|
4
|
+
require_relative "windows/structs"
|
|
5
|
+
require_relative "windows/functions"
|
|
6
6
|
|
|
7
7
|
# The Win32 module serves as a namespace only.
|
|
8
8
|
module Win32
|
|
@@ -76,7 +76,7 @@ module Win32
|
|
|
76
76
|
KERNEL_DRIVER = SERVICE_KERNEL_DRIVER
|
|
77
77
|
|
|
78
78
|
# File system driver service
|
|
79
|
-
FILE_SYSTEM_DRIVER
|
|
79
|
+
FILE_SYSTEM_DRIVER = SERVICE_FILE_SYSTEM_DRIVER
|
|
80
80
|
|
|
81
81
|
# Service that runs in its own process
|
|
82
82
|
WIN32_OWN_PROCESS = SERVICE_WIN32_OWN_PROCESS
|
|
@@ -190,7 +190,7 @@ module Win32
|
|
|
190
190
|
# :stopdoc: #
|
|
191
191
|
|
|
192
192
|
StatusStruct = Struct.new(
|
|
193
|
-
|
|
193
|
+
"ServiceStatus",
|
|
194
194
|
:service_type,
|
|
195
195
|
:current_state,
|
|
196
196
|
:controls_accepted,
|
|
@@ -204,7 +204,7 @@ module Win32
|
|
|
204
204
|
)
|
|
205
205
|
|
|
206
206
|
ConfigStruct = Struct.new(
|
|
207
|
-
|
|
207
|
+
"ServiceConfigInfo",
|
|
208
208
|
:service_type,
|
|
209
209
|
:start_type,
|
|
210
210
|
:error_control,
|
|
@@ -217,7 +217,7 @@ module Win32
|
|
|
217
217
|
)
|
|
218
218
|
|
|
219
219
|
ServiceStruct = Struct.new(
|
|
220
|
-
|
|
220
|
+
"ServiceInfo",
|
|
221
221
|
:service_name,
|
|
222
222
|
:display_name,
|
|
223
223
|
:service_type,
|
|
@@ -291,51 +291,52 @@ module Win32
|
|
|
291
291
|
# :display_name => 'This is some service',
|
|
292
292
|
# )
|
|
293
293
|
#
|
|
294
|
-
def initialize(options={})
|
|
294
|
+
def initialize(options = {})
|
|
295
295
|
unless options.is_a?(Hash)
|
|
296
|
-
raise ArgumentError,
|
|
296
|
+
raise ArgumentError, "options parameter must be a hash"
|
|
297
297
|
end
|
|
298
298
|
|
|
299
299
|
if options.empty?
|
|
300
|
-
raise ArgumentError,
|
|
300
|
+
raise ArgumentError, "no options provided"
|
|
301
301
|
end
|
|
302
302
|
|
|
303
303
|
opts = {
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
304
|
+
"display_name" => nil,
|
|
305
|
+
"desired_access" => SERVICE_ALL_ACCESS,
|
|
306
|
+
"service_type" => SERVICE_WIN32_OWN_PROCESS,
|
|
307
|
+
"start_type" => SERVICE_DEMAND_START,
|
|
308
|
+
"error_control" => SERVICE_ERROR_NORMAL,
|
|
309
|
+
"binary_path_name" => nil,
|
|
310
|
+
"load_order_group" => nil,
|
|
311
|
+
"dependencies" => nil,
|
|
312
|
+
"service_start_name" => nil,
|
|
313
|
+
"password" => nil,
|
|
314
|
+
"description" => nil,
|
|
315
|
+
"failure_reset_period" => nil,
|
|
316
|
+
"failure_reboot_message" => nil,
|
|
317
|
+
"failure_command" => nil,
|
|
318
|
+
"failure_actions" => nil,
|
|
319
|
+
"failure_delay" => 0,
|
|
320
|
+
"host" => nil,
|
|
321
|
+
"service_name" => nil,
|
|
322
322
|
}
|
|
323
323
|
|
|
324
324
|
# Validate the hash options
|
|
325
|
-
options.each{ |key, value|
|
|
325
|
+
options.each { |key, value|
|
|
326
326
|
key = key.to_s.downcase
|
|
327
327
|
unless opts.include?(key)
|
|
328
328
|
raise ArgumentError, "Invalid option '#{key}'"
|
|
329
329
|
end
|
|
330
|
+
|
|
330
331
|
opts[key] = value
|
|
331
332
|
}
|
|
332
333
|
|
|
333
|
-
unless opts[
|
|
334
|
-
raise ArgumentError,
|
|
334
|
+
unless opts["service_name"]
|
|
335
|
+
raise ArgumentError, "No service_name specified"
|
|
335
336
|
end
|
|
336
337
|
|
|
337
|
-
service_name = opts.delete(
|
|
338
|
-
host = opts.delete(
|
|
338
|
+
service_name = opts.delete("service_name")
|
|
339
|
+
host = opts.delete("host")
|
|
339
340
|
|
|
340
341
|
raise TypeError unless service_name.is_a?(String)
|
|
341
342
|
raise TypeError if host && !host.is_a?(String)
|
|
@@ -343,16 +344,16 @@ module Win32
|
|
|
343
344
|
begin
|
|
344
345
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CREATE_SERVICE)
|
|
345
346
|
|
|
346
|
-
FFI.raise_windows_error(
|
|
347
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
347
348
|
|
|
348
349
|
# Display name defaults to service_name
|
|
349
|
-
opts[
|
|
350
|
+
opts["display_name"] ||= service_name
|
|
350
351
|
|
|
351
|
-
dependencies = opts[
|
|
352
|
+
dependencies = opts["dependencies"]
|
|
352
353
|
|
|
353
354
|
if dependencies && !dependencies.empty?
|
|
354
355
|
unless dependencies.is_a?(Array) || dependencies.is_a?(String)
|
|
355
|
-
raise TypeError,
|
|
356
|
+
raise TypeError, "dependencies must be a string or array"
|
|
356
357
|
end
|
|
357
358
|
|
|
358
359
|
if dependencies.is_a?(Array)
|
|
@@ -366,24 +367,24 @@ module Win32
|
|
|
366
367
|
handle_scs = CreateService(
|
|
367
368
|
handle_scm,
|
|
368
369
|
service_name,
|
|
369
|
-
opts[
|
|
370
|
-
opts[
|
|
371
|
-
opts[
|
|
372
|
-
opts[
|
|
373
|
-
opts[
|
|
374
|
-
opts[
|
|
375
|
-
opts[
|
|
370
|
+
opts["display_name"],
|
|
371
|
+
opts["desired_access"],
|
|
372
|
+
opts["service_type"],
|
|
373
|
+
opts["start_type"],
|
|
374
|
+
opts["error_control"],
|
|
375
|
+
opts["binary_path_name"],
|
|
376
|
+
opts["load_order_group"],
|
|
376
377
|
nil,
|
|
377
378
|
dependencies,
|
|
378
|
-
opts[
|
|
379
|
-
opts[
|
|
379
|
+
opts["service_start_name"],
|
|
380
|
+
opts["password"]
|
|
380
381
|
)
|
|
381
382
|
|
|
382
|
-
FFI.raise_windows_error(
|
|
383
|
+
FFI.raise_windows_error("CreateService") if handle_scs == 0
|
|
383
384
|
|
|
384
|
-
if opts[
|
|
385
|
+
if opts["description"]
|
|
385
386
|
description = SERVICE_DESCRIPTION.new
|
|
386
|
-
description[:lpDescription] = FFI::MemoryPointer.from_string(opts[
|
|
387
|
+
description[:lpDescription] = FFI::MemoryPointer.from_string(opts["description"])
|
|
387
388
|
|
|
388
389
|
bool = ChangeServiceConfig2(
|
|
389
390
|
handle_scs,
|
|
@@ -391,20 +392,17 @@ module Win32
|
|
|
391
392
|
description
|
|
392
393
|
)
|
|
393
394
|
|
|
394
|
-
FFI.raise_windows_error(
|
|
395
|
+
FFI.raise_windows_error("ChangeServiceConfig2") unless bool
|
|
395
396
|
end
|
|
396
397
|
|
|
397
|
-
if opts[
|
|
398
|
-
|
|
399
|
-
then
|
|
398
|
+
if opts["failure_reset_period"] || opts["failure_reboot_message"] ||
|
|
399
|
+
opts["failure_command"] || opts["failure_actions"]
|
|
400
400
|
self.class.configure_failure_actions(handle_scs, opts)
|
|
401
401
|
end
|
|
402
402
|
ensure
|
|
403
403
|
self.class.close_service_handle(handle_scs)
|
|
404
404
|
self.class.close_service_handle(handle_scm)
|
|
405
405
|
end
|
|
406
|
-
|
|
407
|
-
self
|
|
408
406
|
end
|
|
409
407
|
|
|
410
408
|
# Configures the named +service+ on +host+, or the local host if no host
|
|
@@ -450,63 +448,67 @@ module Win32
|
|
|
450
448
|
# :description => 'A custom service I wrote just for fun'
|
|
451
449
|
# )
|
|
452
450
|
#
|
|
453
|
-
def self.configure(options={})
|
|
451
|
+
def self.configure(options = {})
|
|
454
452
|
unless options.is_a?(Hash)
|
|
455
|
-
raise ArgumentError,
|
|
453
|
+
raise ArgumentError, "options parameter must be a hash"
|
|
456
454
|
end
|
|
457
455
|
|
|
458
456
|
if options.empty?
|
|
459
|
-
raise ArgumentError,
|
|
457
|
+
raise ArgumentError, "no options provided"
|
|
460
458
|
end
|
|
461
459
|
|
|
462
460
|
opts = {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
461
|
+
"service_type" => SERVICE_NO_CHANGE,
|
|
462
|
+
"start_type" => SERVICE_NO_CHANGE,
|
|
463
|
+
"error_control" => SERVICE_NO_CHANGE,
|
|
464
|
+
"binary_path_name" => nil,
|
|
465
|
+
"load_order_group" => nil,
|
|
466
|
+
"dependencies" => nil,
|
|
467
|
+
"service_start_name" => nil,
|
|
468
|
+
"password" => nil,
|
|
469
|
+
"display_name" => nil,
|
|
470
|
+
"description" => nil,
|
|
471
|
+
"failure_reset_period" => nil,
|
|
472
|
+
"failure_reboot_message" => nil,
|
|
473
|
+
"failure_command" => nil,
|
|
474
|
+
"failure_actions" => nil,
|
|
475
|
+
"failure_delay" => 0,
|
|
476
|
+
"service_name" => nil,
|
|
477
|
+
"host" => nil,
|
|
478
|
+
"delayed_start" => false,
|
|
481
479
|
}
|
|
482
480
|
|
|
483
481
|
# Validate the hash options
|
|
484
|
-
options.each{ |key, value|
|
|
482
|
+
options.each { |key, value|
|
|
485
483
|
key = key.to_s.downcase
|
|
486
484
|
unless opts.include?(key)
|
|
487
485
|
raise ArgumentError, "Invalid option '#{key}'"
|
|
488
486
|
end
|
|
487
|
+
|
|
489
488
|
opts[key] = value
|
|
490
489
|
}
|
|
491
490
|
|
|
492
|
-
unless opts[
|
|
493
|
-
raise ArgumentError,
|
|
491
|
+
unless opts["service_name"]
|
|
492
|
+
raise ArgumentError, "No service_name specified"
|
|
494
493
|
end
|
|
495
494
|
|
|
496
|
-
service = opts.delete(
|
|
497
|
-
host = opts.delete(
|
|
495
|
+
service = opts.delete("service_name")
|
|
496
|
+
host = opts.delete("host")
|
|
498
497
|
|
|
499
498
|
raise TypeError unless service.is_a?(String)
|
|
500
|
-
|
|
499
|
+
|
|
500
|
+
if host
|
|
501
|
+
raise TypeError unless host.is_a?(String)
|
|
502
|
+
end
|
|
501
503
|
|
|
502
504
|
begin
|
|
503
505
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CONNECT)
|
|
504
506
|
|
|
505
|
-
FFI.raise_windows_error(
|
|
507
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
506
508
|
|
|
507
509
|
desired_access = SERVICE_CHANGE_CONFIG
|
|
508
510
|
|
|
509
|
-
if opts[
|
|
511
|
+
if opts["failure_actions"]
|
|
510
512
|
desired_access |= SERVICE_START
|
|
511
513
|
end
|
|
512
514
|
|
|
@@ -516,13 +518,13 @@ module Win32
|
|
|
516
518
|
desired_access
|
|
517
519
|
)
|
|
518
520
|
|
|
519
|
-
FFI.raise_windows_error(
|
|
521
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
520
522
|
|
|
521
|
-
dependencies = opts[
|
|
523
|
+
dependencies = opts["dependencies"]
|
|
522
524
|
|
|
523
525
|
if dependencies && !dependencies.empty?
|
|
524
526
|
unless dependencies.is_a?(Array) || dependencies.is_a?(String)
|
|
525
|
-
raise TypeError,
|
|
527
|
+
raise TypeError, "dependencies must be a string or array"
|
|
526
528
|
end
|
|
527
529
|
|
|
528
530
|
if dependencies.is_a?(Array)
|
|
@@ -534,23 +536,23 @@ module Win32
|
|
|
534
536
|
|
|
535
537
|
bool = ChangeServiceConfig(
|
|
536
538
|
handle_scs,
|
|
537
|
-
opts[
|
|
538
|
-
opts[
|
|
539
|
-
opts[
|
|
540
|
-
opts[
|
|
541
|
-
opts[
|
|
539
|
+
opts["service_type"],
|
|
540
|
+
opts["start_type"],
|
|
541
|
+
opts["error_control"],
|
|
542
|
+
opts["binary_path_name"],
|
|
543
|
+
opts["load_order_group"],
|
|
542
544
|
nil,
|
|
543
545
|
dependencies,
|
|
544
|
-
opts[
|
|
545
|
-
opts[
|
|
546
|
-
opts[
|
|
546
|
+
opts["service_start_name"],
|
|
547
|
+
opts["password"],
|
|
548
|
+
opts["display_name"]
|
|
547
549
|
)
|
|
548
550
|
|
|
549
|
-
FFI.raise_windows_error(
|
|
551
|
+
FFI.raise_windows_error("ChangeServiceConfig") unless bool
|
|
550
552
|
|
|
551
|
-
if opts[
|
|
553
|
+
if opts["description"]
|
|
552
554
|
description = SERVICE_DESCRIPTION.new
|
|
553
|
-
description[:lpDescription] = FFI::MemoryPointer.from_string(opts[
|
|
555
|
+
description[:lpDescription] = FFI::MemoryPointer.from_string(opts["description"])
|
|
554
556
|
|
|
555
557
|
bool = ChangeServiceConfig2(
|
|
556
558
|
handle_scs,
|
|
@@ -558,12 +560,12 @@ module Win32
|
|
|
558
560
|
description
|
|
559
561
|
)
|
|
560
562
|
|
|
561
|
-
FFI.raise_windows_error(
|
|
563
|
+
FFI.raise_windows_error("ChangeServiceConfig2") unless bool
|
|
562
564
|
end
|
|
563
565
|
|
|
564
|
-
if opts[
|
|
566
|
+
if opts["delayed_start"]
|
|
565
567
|
delayed_start = SERVICE_DELAYED_AUTO_START_INFO.new
|
|
566
|
-
delayed_start[:fDelayedAutostart] = opts[
|
|
568
|
+
delayed_start[:fDelayedAutostart] = opts["delayed_start"]
|
|
567
569
|
|
|
568
570
|
bool = ChangeServiceConfig2(
|
|
569
571
|
handle_scs,
|
|
@@ -571,12 +573,11 @@ module Win32
|
|
|
571
573
|
delayed_start
|
|
572
574
|
)
|
|
573
575
|
|
|
574
|
-
FFI.raise_windows_error(
|
|
576
|
+
FFI.raise_windows_error("ChangeServiceConfig2") unless bool
|
|
575
577
|
end
|
|
576
578
|
|
|
577
|
-
if opts[
|
|
578
|
-
|
|
579
|
-
then
|
|
579
|
+
if opts["failure_reset_period"] || opts["failure_reboot_message"] ||
|
|
580
|
+
opts["failure_command"] || opts["failure_actions"]
|
|
580
581
|
configure_failure_actions(handle_scs, opts)
|
|
581
582
|
end
|
|
582
583
|
ensure
|
|
@@ -594,13 +595,13 @@ module Win32
|
|
|
594
595
|
#
|
|
595
596
|
# Service.exists?('W32Time') => true
|
|
596
597
|
#
|
|
597
|
-
def self.exists?(service, host=nil)
|
|
598
|
+
def self.exists?(service, host = nil)
|
|
598
599
|
bool = false
|
|
599
600
|
|
|
600
601
|
begin
|
|
601
602
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_ENUMERATE_SERVICE)
|
|
602
603
|
|
|
603
|
-
FFI.raise_windows_error(
|
|
604
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
604
605
|
|
|
605
606
|
handle_scs = OpenService(handle_scm, service, SERVICE_QUERY_STATUS)
|
|
606
607
|
bool = true if handle_scs > 0
|
|
@@ -624,13 +625,13 @@ module Win32
|
|
|
624
625
|
#
|
|
625
626
|
# Service.get_display_name('W32Time') => 'Windows Time'
|
|
626
627
|
#
|
|
627
|
-
def self.get_display_name(service, host=nil)
|
|
628
|
+
def self.get_display_name(service, host = nil)
|
|
628
629
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CONNECT)
|
|
629
630
|
|
|
630
|
-
FFI.raise_windows_error(
|
|
631
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
631
632
|
|
|
632
633
|
display_name = FFI::MemoryPointer.new(260)
|
|
633
|
-
display_size
|
|
634
|
+
display_size = FFI::MemoryPointer.new(:ulong)
|
|
634
635
|
display_size.write_ulong(display_name.size)
|
|
635
636
|
|
|
636
637
|
begin
|
|
@@ -641,8 +642,7 @@ module Win32
|
|
|
641
642
|
display_size
|
|
642
643
|
)
|
|
643
644
|
|
|
644
|
-
|
|
645
|
-
FFI.raise_windows_error('OpenSCManager') unless bool
|
|
645
|
+
FFI.raise_windows_error("OpenSCManager") unless bool
|
|
646
646
|
ensure
|
|
647
647
|
close_service_handle(handle_scm)
|
|
648
648
|
end
|
|
@@ -662,10 +662,10 @@ module Win32
|
|
|
662
662
|
#
|
|
663
663
|
# Service.get_service_name('Windows Time') => 'W32Time'
|
|
664
664
|
#
|
|
665
|
-
def self.get_service_name(display_name, host=nil)
|
|
665
|
+
def self.get_service_name(display_name, host = nil)
|
|
666
666
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CONNECT)
|
|
667
667
|
|
|
668
|
-
FFI.raise_windows_error(
|
|
668
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
669
669
|
|
|
670
670
|
service_name = FFI::MemoryPointer.new(260)
|
|
671
671
|
service_size = FFI::MemoryPointer.new(:ulong)
|
|
@@ -679,12 +679,13 @@ module Win32
|
|
|
679
679
|
service_size
|
|
680
680
|
)
|
|
681
681
|
|
|
682
|
-
FFI.raise_windows_error(
|
|
682
|
+
FFI.raise_windows_error("GetServiceKeyName") unless bool
|
|
683
683
|
ensure
|
|
684
684
|
close_service_handle(handle_scm)
|
|
685
685
|
end
|
|
686
686
|
|
|
687
|
-
|
|
687
|
+
# Return a lowercase, UTF-8 encoded string
|
|
688
|
+
service_name.read_string.downcase.force_encoding("UTF-8")
|
|
688
689
|
end
|
|
689
690
|
|
|
690
691
|
# Attempts to start the named +service+ on +host+, or the local machine
|
|
@@ -699,39 +700,38 @@ module Win32
|
|
|
699
700
|
# # Start 'SomeSvc' on host 'foo', passing 'hello' as an argument
|
|
700
701
|
# Service.start('SomeSvc', 'foo', 'hello') => self
|
|
701
702
|
#
|
|
702
|
-
def self.start(service, host=nil, *args)
|
|
703
|
+
def self.start(service, host = nil, *args)
|
|
703
704
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CONNECT)
|
|
704
705
|
|
|
705
|
-
FFI.raise_windows_error(
|
|
706
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
706
707
|
|
|
707
708
|
begin
|
|
708
709
|
handle_scs = OpenService(handle_scm, service, SERVICE_START)
|
|
709
710
|
|
|
710
|
-
FFI.raise_windows_error(
|
|
711
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
711
712
|
|
|
712
713
|
num_args = 0
|
|
713
714
|
|
|
714
715
|
if args.empty?
|
|
715
|
-
|
|
716
|
+
nil # rubocop:disable Lint/Void
|
|
716
717
|
else
|
|
717
|
-
str_ptrs = []
|
|
718
718
|
num_args = args.size
|
|
719
719
|
|
|
720
|
-
args.
|
|
721
|
-
|
|
720
|
+
str_ptrs = args.map { |string|
|
|
721
|
+
FFI::MemoryPointer.from_string(string)
|
|
722
722
|
}
|
|
723
723
|
|
|
724
724
|
str_ptrs << nil
|
|
725
725
|
|
|
726
726
|
vector = FFI::MemoryPointer.new(:pointer, str_ptrs.size)
|
|
727
727
|
|
|
728
|
-
str_ptrs.each_with_index{ |p, i|
|
|
728
|
+
str_ptrs.each_with_index { |p, i|
|
|
729
729
|
vector[i].put_pointer(0, p)
|
|
730
730
|
}
|
|
731
731
|
end
|
|
732
732
|
|
|
733
733
|
unless StartService(handle_scs, num_args, vector)
|
|
734
|
-
FFI.raise_windows_error(
|
|
734
|
+
FFI.raise_windows_error("StartService")
|
|
735
735
|
end
|
|
736
736
|
|
|
737
737
|
ensure
|
|
@@ -752,7 +752,7 @@ module Win32
|
|
|
752
752
|
#
|
|
753
753
|
# Service.stop('W32Time') => self
|
|
754
754
|
#
|
|
755
|
-
def self.stop(service, host=nil)
|
|
755
|
+
def self.stop(service, host = nil)
|
|
756
756
|
service_signal = SERVICE_STOP
|
|
757
757
|
control_signal = SERVICE_CONTROL_STOP
|
|
758
758
|
send_signal(service, host, service_signal, control_signal)
|
|
@@ -773,7 +773,7 @@ module Win32
|
|
|
773
773
|
#
|
|
774
774
|
# Service.pause('Schedule') => self
|
|
775
775
|
#
|
|
776
|
-
def self.pause(service, host=nil)
|
|
776
|
+
def self.pause(service, host = nil)
|
|
777
777
|
service_signal = SERVICE_PAUSE_CONTINUE
|
|
778
778
|
control_signal = SERVICE_CONTROL_PAUSE
|
|
779
779
|
send_signal(service, host, service_signal, control_signal)
|
|
@@ -790,7 +790,7 @@ module Win32
|
|
|
790
790
|
#
|
|
791
791
|
# Service.resume('Schedule') => self
|
|
792
792
|
#
|
|
793
|
-
def self.resume(service, host=nil)
|
|
793
|
+
def self.resume(service, host = nil)
|
|
794
794
|
service_signal = SERVICE_PAUSE_CONTINUE
|
|
795
795
|
control_signal = SERVICE_CONTROL_CONTINUE
|
|
796
796
|
send_signal(service, host, service_signal, control_signal)
|
|
@@ -810,18 +810,18 @@ module Win32
|
|
|
810
810
|
#
|
|
811
811
|
# Service.delete('SomeService') => self
|
|
812
812
|
#
|
|
813
|
-
def self.delete(service, host=nil)
|
|
813
|
+
def self.delete(service, host = nil)
|
|
814
814
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CREATE_SERVICE)
|
|
815
815
|
|
|
816
|
-
FFI.raise_windows_error(
|
|
816
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
817
817
|
|
|
818
818
|
begin
|
|
819
819
|
handle_scs = OpenService(handle_scm, service, DELETE)
|
|
820
820
|
|
|
821
|
-
FFI.raise_windows_error(
|
|
821
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
822
822
|
|
|
823
823
|
unless DeleteService(handle_scs)
|
|
824
|
-
FFI.raise_windows_error(
|
|
824
|
+
FFI.raise_windows_error("DeleteService")
|
|
825
825
|
end
|
|
826
826
|
ensure
|
|
827
827
|
close_service_handle(handle_scs)
|
|
@@ -843,17 +843,17 @@ module Win32
|
|
|
843
843
|
# is returned with the Service.services method, but is faster for
|
|
844
844
|
# looking up basic information for a single service.
|
|
845
845
|
#
|
|
846
|
-
def self.config_info(service, host=nil)
|
|
846
|
+
def self.config_info(service, host = nil)
|
|
847
847
|
raise TypeError if host && !host.is_a?(String)
|
|
848
848
|
|
|
849
849
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_ENUMERATE_SERVICE)
|
|
850
850
|
|
|
851
|
-
FFI.raise_windows_error(
|
|
851
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
852
852
|
|
|
853
853
|
begin
|
|
854
854
|
handle_scs = OpenService(handle_scm, service, SERVICE_QUERY_CONFIG)
|
|
855
855
|
|
|
856
|
-
FFI.raise_windows_error(
|
|
856
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
857
857
|
|
|
858
858
|
# First, get the buf size needed
|
|
859
859
|
bytes = FFI::MemoryPointer.new(:ulong)
|
|
@@ -861,7 +861,7 @@ module Win32
|
|
|
861
861
|
bool = QueryServiceConfig(handle_scs, nil, 0, bytes)
|
|
862
862
|
|
|
863
863
|
if !bool && FFI.errno != ERROR_INSUFFICIENT_BUFFER
|
|
864
|
-
FFI.raise_windows_error(
|
|
864
|
+
FFI.raise_windows_error("QueryServiceConfig")
|
|
865
865
|
end
|
|
866
866
|
|
|
867
867
|
buf = FFI::MemoryPointer.new(:char, bytes.read_ulong)
|
|
@@ -871,7 +871,7 @@ module Win32
|
|
|
871
871
|
|
|
872
872
|
struct = QUERY_SERVICE_CONFIG.new(buf) # cast the buffer
|
|
873
873
|
|
|
874
|
-
FFI.raise_windows_error(
|
|
874
|
+
FFI.raise_windows_error("QueryServiceConfig") unless bool
|
|
875
875
|
ensure
|
|
876
876
|
close_service_handle(handle_scs)
|
|
877
877
|
close_service_handle(handle_scm)
|
|
@@ -897,7 +897,7 @@ module Win32
|
|
|
897
897
|
#
|
|
898
898
|
# Service.status('W32Time') => <struct Struct::ServiceStatus ...>
|
|
899
899
|
#
|
|
900
|
-
def self.status(service, host=nil)
|
|
900
|
+
def self.status(service, host = nil)
|
|
901
901
|
status = SERVICE_STATUS_PROCESS.new
|
|
902
902
|
bytes = FFI::MemoryPointer.new(:ulong)
|
|
903
903
|
|
|
@@ -911,7 +911,7 @@ module Win32
|
|
|
911
911
|
bytes
|
|
912
912
|
)
|
|
913
913
|
|
|
914
|
-
FFI.raise_windows_error(
|
|
914
|
+
FFI.raise_windows_error("QueryServiceStatusEx") unless bool
|
|
915
915
|
end
|
|
916
916
|
end
|
|
917
917
|
|
|
@@ -957,7 +957,7 @@ module Win32
|
|
|
957
957
|
# # Enumerate over all 'network' services locally
|
|
958
958
|
# Service.services(nil, 'network'){ |service| p service }
|
|
959
959
|
#
|
|
960
|
-
def self.services(host=nil, group=nil)
|
|
960
|
+
def self.services(host = nil, group = nil)
|
|
961
961
|
unless host.nil?
|
|
962
962
|
raise TypeError unless host.is_a?(String) # Avoid strange errors
|
|
963
963
|
end
|
|
@@ -968,7 +968,7 @@ module Win32
|
|
|
968
968
|
|
|
969
969
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_ENUMERATE_SERVICE)
|
|
970
970
|
|
|
971
|
-
FFI.raise_windows_error(
|
|
971
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
972
972
|
|
|
973
973
|
bytes_needed = FFI::MemoryPointer.new(:ulong)
|
|
974
974
|
services_returned = FFI::MemoryPointer.new(:ulong)
|
|
@@ -992,7 +992,7 @@ module Win32
|
|
|
992
992
|
if !bool && FFI.errno == ERROR_MORE_DATA
|
|
993
993
|
service_buf = FFI::MemoryPointer.new(:char, bytes_needed.read_ulong)
|
|
994
994
|
else
|
|
995
|
-
FFI.raise_windows_error(
|
|
995
|
+
FFI.raise_windows_error("EnumServiceStatusEx")
|
|
996
996
|
end
|
|
997
997
|
|
|
998
998
|
bool = EnumServicesStatusEx(
|
|
@@ -1008,13 +1008,13 @@ module Win32
|
|
|
1008
1008
|
group
|
|
1009
1009
|
)
|
|
1010
1010
|
|
|
1011
|
-
FFI.raise_windows_error(
|
|
1011
|
+
FFI.raise_windows_error("EnumServiceStatusEx") unless bool
|
|
1012
1012
|
|
|
1013
1013
|
num_services = services_returned.read_ulong
|
|
1014
1014
|
|
|
1015
1015
|
services_array = [] unless block_given?
|
|
1016
1016
|
|
|
1017
|
-
1.upto(num_services){ |num|
|
|
1017
|
+
1.upto(num_services) { |num|
|
|
1018
1018
|
# Cast the buffer
|
|
1019
1019
|
struct = ENUM_SERVICE_STATUS_PROCESS.new(service_buf)
|
|
1020
1020
|
|
|
@@ -1040,7 +1040,7 @@ module Win32
|
|
|
1040
1040
|
SERVICE_QUERY_CONFIG
|
|
1041
1041
|
)
|
|
1042
1042
|
|
|
1043
|
-
FFI.raise_windows_error(
|
|
1043
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
1044
1044
|
|
|
1045
1045
|
config_struct = get_config_info(handle_scs)
|
|
1046
1046
|
|
|
@@ -1059,14 +1059,14 @@ module Win32
|
|
|
1059
1059
|
buf = get_config2_info(handle_scs, SERVICE_CONFIG_DESCRIPTION)
|
|
1060
1060
|
|
|
1061
1061
|
if buf.is_a?(Numeric) || buf.read_pointer.null?
|
|
1062
|
-
description =
|
|
1062
|
+
description = ""
|
|
1063
1063
|
else
|
|
1064
1064
|
description = buf.read_pointer.read_string
|
|
1065
1065
|
end
|
|
1066
1066
|
rescue
|
|
1067
1067
|
# While being annoying, not being able to get a description is not exceptional
|
|
1068
1068
|
warn "WARNING: Failed to retrieve description for the #{service_name} service."
|
|
1069
|
-
description =
|
|
1069
|
+
description = ""
|
|
1070
1070
|
end
|
|
1071
1071
|
|
|
1072
1072
|
delayed_start = delayed_start(service_name)
|
|
@@ -1111,11 +1111,11 @@ module Win32
|
|
|
1111
1111
|
|
|
1112
1112
|
actions = {}
|
|
1113
1113
|
|
|
1114
|
-
num_actions.times{ |n|
|
|
1114
|
+
num_actions.times { |n|
|
|
1115
1115
|
sc_action = SC_ACTION.new(action_ptr[n * SC_ACTION.size])
|
|
1116
1116
|
delay = sc_action[:Delay]
|
|
1117
1117
|
action_type = get_action_type(sc_action[:Type])
|
|
1118
|
-
actions[n+1] = {:
|
|
1118
|
+
actions[n + 1] = { action_type: action_type, delay: delay }
|
|
1119
1119
|
}
|
|
1120
1120
|
end
|
|
1121
1121
|
else
|
|
@@ -1165,9 +1165,9 @@ module Win32
|
|
|
1165
1165
|
)
|
|
1166
1166
|
|
|
1167
1167
|
if block_given?
|
|
1168
|
-
|
|
1168
|
+
yield struct
|
|
1169
1169
|
else
|
|
1170
|
-
|
|
1170
|
+
services_array << struct
|
|
1171
1171
|
end
|
|
1172
1172
|
|
|
1173
1173
|
service_buf += ENUM_SERVICE_STATUS_PROCESS.size
|
|
@@ -1197,7 +1197,7 @@ module Win32
|
|
|
1197
1197
|
def self.delayed_start(service, host = nil)
|
|
1198
1198
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_ENUMERATE_SERVICE)
|
|
1199
1199
|
|
|
1200
|
-
FFI.raise_windows_error(
|
|
1200
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
1201
1201
|
|
|
1202
1202
|
handle_scs = OpenService(
|
|
1203
1203
|
handle_scm,
|
|
@@ -1205,17 +1205,17 @@ module Win32
|
|
|
1205
1205
|
SERVICE_QUERY_CONFIG
|
|
1206
1206
|
)
|
|
1207
1207
|
|
|
1208
|
-
FFI.raise_windows_error(
|
|
1208
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
1209
1209
|
|
|
1210
1210
|
delayed_start_buf = get_config2_info(handle_scs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO)
|
|
1211
1211
|
if delayed_start_buf.is_a?(FFI::MemoryPointer)
|
|
1212
1212
|
delayed_start_info = SERVICE_DELAYED_AUTO_START_INFO.new(delayed_start_buf)
|
|
1213
|
-
|
|
1213
|
+
delayed_start_info[:fDelayedAutostart]
|
|
1214
1214
|
else
|
|
1215
|
-
|
|
1215
|
+
false
|
|
1216
1216
|
end
|
|
1217
1217
|
rescue SystemCallError
|
|
1218
|
-
|
|
1218
|
+
nil
|
|
1219
1219
|
ensure
|
|
1220
1220
|
close_service_handle(handle_scs)
|
|
1221
1221
|
close_service_handle(handle_scm)
|
|
@@ -1250,12 +1250,12 @@ module Win32
|
|
|
1250
1250
|
# @see Windows::ServiceConstants
|
|
1251
1251
|
#
|
|
1252
1252
|
def self.open_service(scm_handle, service_name, desired_access)
|
|
1253
|
-
|
|
1253
|
+
service_handle = OpenService(
|
|
1254
1254
|
scm_handle,
|
|
1255
1255
|
service_name,
|
|
1256
1256
|
desired_access
|
|
1257
1257
|
)
|
|
1258
|
-
FFI.raise_windows_error(
|
|
1258
|
+
FFI.raise_windows_error("OpenService") if service_handle == 0
|
|
1259
1259
|
|
|
1260
1260
|
if block_given?
|
|
1261
1261
|
yield service_handle
|
|
@@ -1288,7 +1288,7 @@ module Win32
|
|
|
1288
1288
|
#
|
|
1289
1289
|
def self.open_sc_manager(host = nil, desired_access = SC_MANAGER_CONNECT)
|
|
1290
1290
|
scm_handle = OpenSCManager(host, nil, desired_access)
|
|
1291
|
-
FFI.raise_windows_error(
|
|
1291
|
+
FFI.raise_windows_error("OpenSCManager") if scm_handle == 0
|
|
1292
1292
|
|
|
1293
1293
|
if block_given?
|
|
1294
1294
|
yield scm_handle
|
|
@@ -1299,12 +1299,10 @@ module Win32
|
|
|
1299
1299
|
close_service_handle(scm_handle) if block_given?
|
|
1300
1300
|
end
|
|
1301
1301
|
|
|
1302
|
-
private
|
|
1303
|
-
|
|
1304
1302
|
# Configures failure actions for a given service.
|
|
1305
1303
|
#
|
|
1306
1304
|
def self.configure_failure_actions(handle_scs, opts)
|
|
1307
|
-
if opts[
|
|
1305
|
+
if opts["failure_actions"]
|
|
1308
1306
|
token_handle = FFI::MemoryPointer.new(:ulong)
|
|
1309
1307
|
|
|
1310
1308
|
bool = OpenProcessToken(
|
|
@@ -1316,7 +1314,7 @@ module Win32
|
|
|
1316
1314
|
unless bool
|
|
1317
1315
|
error = FFI.errno
|
|
1318
1316
|
close_service_handle(handle_scs)
|
|
1319
|
-
raise SystemCallError.new(
|
|
1317
|
+
raise SystemCallError.new("OpenProcessToken", error)
|
|
1320
1318
|
end
|
|
1321
1319
|
|
|
1322
1320
|
token_handle = token_handle.read_ulong
|
|
@@ -1324,10 +1322,10 @@ module Win32
|
|
|
1324
1322
|
# Get the LUID for shutdown privilege.
|
|
1325
1323
|
luid = LUID.new
|
|
1326
1324
|
|
|
1327
|
-
unless LookupPrivilegeValue(
|
|
1325
|
+
unless LookupPrivilegeValue("", "SeShutdownPrivilege", luid)
|
|
1328
1326
|
error = FFI.errno
|
|
1329
1327
|
close_service_handle(handle_scs)
|
|
1330
|
-
raise SystemCallError.new(
|
|
1328
|
+
raise SystemCallError.new("LookupPrivilegeValue", error)
|
|
1331
1329
|
end
|
|
1332
1330
|
|
|
1333
1331
|
luid_and_attrs = LUID_AND_ATTRIBUTES.new
|
|
@@ -1351,35 +1349,35 @@ module Win32
|
|
|
1351
1349
|
unless bool
|
|
1352
1350
|
error = FFI.errno
|
|
1353
1351
|
close_service_handle(handle_scs)
|
|
1354
|
-
raise SystemCallError.new(
|
|
1352
|
+
raise SystemCallError.new("AdjustTokenPrivileges", error)
|
|
1355
1353
|
end
|
|
1356
1354
|
end
|
|
1357
1355
|
|
|
1358
1356
|
sfa = SERVICE_FAILURE_ACTIONS.new
|
|
1359
1357
|
|
|
1360
|
-
if opts[
|
|
1361
|
-
sfa[:dwResetPeriod] = opts[
|
|
1358
|
+
if opts["failure_reset_period"]
|
|
1359
|
+
sfa[:dwResetPeriod] = opts["failure_reset_period"]
|
|
1362
1360
|
end
|
|
1363
1361
|
|
|
1364
|
-
if opts[
|
|
1365
|
-
sfa[:lpRebootMsg] = FFI::MemoryPointer.from_string(opts[
|
|
1362
|
+
if opts["failure_reboot_message"]
|
|
1363
|
+
sfa[:lpRebootMsg] = FFI::MemoryPointer.from_string(opts["failure_reboot_message"])
|
|
1366
1364
|
end
|
|
1367
1365
|
|
|
1368
|
-
if opts[
|
|
1369
|
-
sfa[:lpCommand] = FFI::MemoryPointer.from_string(opts[
|
|
1366
|
+
if opts["failure_command"]
|
|
1367
|
+
sfa[:lpCommand] = FFI::MemoryPointer.from_string(opts["failure_command"])
|
|
1370
1368
|
end
|
|
1371
1369
|
|
|
1372
|
-
if opts[
|
|
1373
|
-
action_size = opts[
|
|
1370
|
+
if opts["failure_actions"]
|
|
1371
|
+
action_size = opts["failure_actions"].size
|
|
1374
1372
|
action_ptr = FFI::MemoryPointer.new(SC_ACTION, action_size)
|
|
1375
1373
|
|
|
1376
1374
|
actions = action_size.times.collect do |i|
|
|
1377
1375
|
SC_ACTION.new(action_ptr + i * SC_ACTION.size)
|
|
1378
1376
|
end
|
|
1379
1377
|
|
|
1380
|
-
opts[
|
|
1378
|
+
opts["failure_actions"].each_with_index { |action, i|
|
|
1381
1379
|
actions[i][:Type] = action
|
|
1382
|
-
actions[i][:Delay] = opts[
|
|
1380
|
+
actions[i][:Delay] = opts["failure_delay"]
|
|
1383
1381
|
}
|
|
1384
1382
|
|
|
1385
1383
|
sfa[:cActions] = action_size
|
|
@@ -1395,7 +1393,7 @@ module Win32
|
|
|
1395
1393
|
unless bool
|
|
1396
1394
|
error = FFI.errno
|
|
1397
1395
|
close_service_handle(handle_scs)
|
|
1398
|
-
raise SystemCallError.new(
|
|
1396
|
+
raise SystemCallError.new("ChangeServiceConfig2", error)
|
|
1399
1397
|
end
|
|
1400
1398
|
end
|
|
1401
1399
|
|
|
@@ -1404,15 +1402,15 @@ module Win32
|
|
|
1404
1402
|
def self.get_action_type(action_type)
|
|
1405
1403
|
case action_type
|
|
1406
1404
|
when SC_ACTION_NONE
|
|
1407
|
-
|
|
1405
|
+
"none"
|
|
1408
1406
|
when SC_ACTION_REBOOT
|
|
1409
|
-
|
|
1407
|
+
"reboot"
|
|
1410
1408
|
when SC_ACTION_RESTART
|
|
1411
|
-
|
|
1409
|
+
"restart"
|
|
1412
1410
|
when SC_ACTION_RUN_COMMAND
|
|
1413
|
-
|
|
1411
|
+
"command"
|
|
1414
1412
|
else
|
|
1415
|
-
|
|
1413
|
+
"unknown"
|
|
1416
1414
|
end
|
|
1417
1415
|
end
|
|
1418
1416
|
|
|
@@ -1434,7 +1432,7 @@ module Win32
|
|
|
1434
1432
|
else
|
|
1435
1433
|
error = FFI.errno
|
|
1436
1434
|
CloseServiceHandle(handle)
|
|
1437
|
-
FFI.raise_windows_error(
|
|
1435
|
+
FFI.raise_windows_error("QueryServiceConfig", error)
|
|
1438
1436
|
end
|
|
1439
1437
|
|
|
1440
1438
|
bytes_needed.clear
|
|
@@ -1448,7 +1446,7 @@ module Win32
|
|
|
1448
1446
|
bytes_needed
|
|
1449
1447
|
)
|
|
1450
1448
|
|
|
1451
|
-
FFI.raise_windows_error(
|
|
1449
|
+
FFI.raise_windows_error("QueryServiceConfig") unless bool
|
|
1452
1450
|
ensure
|
|
1453
1451
|
CloseServiceHandle(handle) unless bool
|
|
1454
1452
|
end
|
|
@@ -1476,7 +1474,7 @@ module Win32
|
|
|
1476
1474
|
return err_num
|
|
1477
1475
|
else
|
|
1478
1476
|
CloseServiceHandle(handle)
|
|
1479
|
-
FFI.raise_windows_error(
|
|
1477
|
+
FFI.raise_windows_error("QueryServiceConfig2", err_num)
|
|
1480
1478
|
end
|
|
1481
1479
|
|
|
1482
1480
|
bytes_needed.clear
|
|
@@ -1491,7 +1489,7 @@ module Win32
|
|
|
1491
1489
|
bytes_needed
|
|
1492
1490
|
)
|
|
1493
1491
|
|
|
1494
|
-
FFI.raise_windows_error(
|
|
1492
|
+
FFI.raise_windows_error("QueryServiceConfig2") unless bool
|
|
1495
1493
|
ensure
|
|
1496
1494
|
CloseServiceHandle(handle) unless bool
|
|
1497
1495
|
end
|
|
@@ -1504,13 +1502,13 @@ module Win32
|
|
|
1504
1502
|
def self.get_error_control(error_control)
|
|
1505
1503
|
case error_control
|
|
1506
1504
|
when SERVICE_ERROR_CRITICAL
|
|
1507
|
-
|
|
1505
|
+
"critical"
|
|
1508
1506
|
when SERVICE_ERROR_IGNORE
|
|
1509
|
-
|
|
1507
|
+
"ignore"
|
|
1510
1508
|
when SERVICE_ERROR_NORMAL
|
|
1511
|
-
|
|
1509
|
+
"normal"
|
|
1512
1510
|
when SERVICE_ERROR_SEVERE
|
|
1513
|
-
|
|
1511
|
+
"severe"
|
|
1514
1512
|
else
|
|
1515
1513
|
nil
|
|
1516
1514
|
end
|
|
@@ -1521,15 +1519,15 @@ module Win32
|
|
|
1521
1519
|
def self.get_start_type(start_type)
|
|
1522
1520
|
case start_type
|
|
1523
1521
|
when SERVICE_AUTO_START
|
|
1524
|
-
|
|
1522
|
+
"auto start"
|
|
1525
1523
|
when SERVICE_BOOT_START
|
|
1526
|
-
|
|
1524
|
+
"boot start"
|
|
1527
1525
|
when SERVICE_DEMAND_START
|
|
1528
|
-
|
|
1526
|
+
"demand start"
|
|
1529
1527
|
when SERVICE_DISABLED
|
|
1530
|
-
|
|
1528
|
+
"disabled"
|
|
1531
1529
|
when SERVICE_SYSTEM_START
|
|
1532
|
-
|
|
1530
|
+
"system start"
|
|
1533
1531
|
else
|
|
1534
1532
|
nil
|
|
1535
1533
|
end
|
|
@@ -1542,39 +1540,39 @@ module Win32
|
|
|
1542
1540
|
array = []
|
|
1543
1541
|
|
|
1544
1542
|
if controls & SERVICE_ACCEPT_NETBINDCHANGE > 0
|
|
1545
|
-
array <<
|
|
1543
|
+
array << "netbind change"
|
|
1546
1544
|
end
|
|
1547
1545
|
|
|
1548
1546
|
if controls & SERVICE_ACCEPT_PARAMCHANGE > 0
|
|
1549
|
-
array <<
|
|
1547
|
+
array << "param change"
|
|
1550
1548
|
end
|
|
1551
1549
|
|
|
1552
1550
|
if controls & SERVICE_ACCEPT_PAUSE_CONTINUE > 0
|
|
1553
|
-
array <<
|
|
1551
|
+
array << "pause continue"
|
|
1554
1552
|
end
|
|
1555
1553
|
|
|
1556
1554
|
if controls & SERVICE_ACCEPT_SHUTDOWN > 0
|
|
1557
|
-
array <<
|
|
1555
|
+
array << "shutdown"
|
|
1558
1556
|
end
|
|
1559
1557
|
|
|
1560
1558
|
if controls & SERVICE_ACCEPT_PRESHUTDOWN > 0
|
|
1561
|
-
array <<
|
|
1559
|
+
array << "pre-shutdown"
|
|
1562
1560
|
end
|
|
1563
1561
|
|
|
1564
1562
|
if controls & SERVICE_ACCEPT_STOP > 0
|
|
1565
|
-
array <<
|
|
1563
|
+
array << "stop"
|
|
1566
1564
|
end
|
|
1567
1565
|
|
|
1568
1566
|
if controls & SERVICE_ACCEPT_HARDWAREPROFILECHANGE > 0
|
|
1569
|
-
array <<
|
|
1567
|
+
array << "hardware profile change"
|
|
1570
1568
|
end
|
|
1571
1569
|
|
|
1572
1570
|
if controls & SERVICE_ACCEPT_POWEREVENT > 0
|
|
1573
|
-
array <<
|
|
1571
|
+
array << "power event"
|
|
1574
1572
|
end
|
|
1575
1573
|
|
|
1576
1574
|
if controls & SERVICE_ACCEPT_SESSIONCHANGE > 0
|
|
1577
|
-
array <<
|
|
1575
|
+
array << "session change"
|
|
1578
1576
|
end
|
|
1579
1577
|
|
|
1580
1578
|
array
|
|
@@ -1585,19 +1583,19 @@ module Win32
|
|
|
1585
1583
|
def self.get_current_state(state)
|
|
1586
1584
|
case state
|
|
1587
1585
|
when SERVICE_CONTINUE_PENDING
|
|
1588
|
-
|
|
1586
|
+
"continue pending"
|
|
1589
1587
|
when SERVICE_PAUSE_PENDING
|
|
1590
|
-
|
|
1588
|
+
"pause pending"
|
|
1591
1589
|
when SERVICE_PAUSED
|
|
1592
|
-
|
|
1590
|
+
"paused"
|
|
1593
1591
|
when SERVICE_RUNNING
|
|
1594
|
-
|
|
1592
|
+
"running"
|
|
1595
1593
|
when SERVICE_START_PENDING
|
|
1596
|
-
|
|
1594
|
+
"start pending"
|
|
1597
1595
|
when SERVICE_STOP_PENDING
|
|
1598
|
-
|
|
1596
|
+
"stop pending"
|
|
1599
1597
|
when SERVICE_STOPPED
|
|
1600
|
-
|
|
1598
|
+
"stopped"
|
|
1601
1599
|
else
|
|
1602
1600
|
nil
|
|
1603
1601
|
end
|
|
@@ -1606,30 +1604,19 @@ module Win32
|
|
|
1606
1604
|
# Converts a service type numeric constant into a human readable string.
|
|
1607
1605
|
#
|
|
1608
1606
|
def self.get_service_type(service_type)
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
'file system driver'
|
|
1612
|
-
when SERVICE_KERNEL_DRIVER
|
|
1613
|
-
'kernel driver'
|
|
1614
|
-
when SERVICE_WIN32_OWN_PROCESS
|
|
1615
|
-
'own process'
|
|
1616
|
-
when SERVICE_WIN32_SHARE_PROCESS
|
|
1617
|
-
'share process'
|
|
1618
|
-
when SERVICE_RECOGNIZER_DRIVER
|
|
1619
|
-
'recognizer driver'
|
|
1620
|
-
when SERVICE_DRIVER
|
|
1621
|
-
'driver'
|
|
1622
|
-
when SERVICE_WIN32
|
|
1623
|
-
'win32'
|
|
1624
|
-
when SERVICE_TYPE_ALL
|
|
1625
|
-
'all'
|
|
1626
|
-
when SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_OWN_PROCESS
|
|
1627
|
-
'own process, interactive'
|
|
1628
|
-
when SERVICE_INTERACTIVE_PROCESS | SERVICE_WIN32_SHARE_PROCESS
|
|
1629
|
-
'share process, interactive'
|
|
1630
|
-
else
|
|
1631
|
-
nil
|
|
1607
|
+
if (service_type & SERVICE_INTERACTIVE_PROCESS) > 0
|
|
1608
|
+
interactive_suffix = ", interactive"
|
|
1632
1609
|
end
|
|
1610
|
+
|
|
1611
|
+
return "share process#{interactive_suffix}" if (service_type & SERVICE_WIN32_SHARE_PROCESS) > 0
|
|
1612
|
+
return "own process#{interactive_suffix}" if (service_type & SERVICE_WIN32_OWN_PROCESS) > 0
|
|
1613
|
+
return "file system driver" if (service_type & SERVICE_FILE_SYSTEM_DRIVER) > 0
|
|
1614
|
+
return "kernel driver" if (service_type & SERVICE_KERNEL_DRIVER) > 0
|
|
1615
|
+
return "recognizer driver" if (service_type & SERVICE_RECOGNIZER_DRIVER) > 0
|
|
1616
|
+
return "driver" if (service_type & SERVICE_DRIVER) > 0
|
|
1617
|
+
return "all" if (service_type == SERVICE_TYPE_ALL) > 0
|
|
1618
|
+
|
|
1619
|
+
"win32" if (service_type & SERVICE_WIN32) > 0
|
|
1633
1620
|
end
|
|
1634
1621
|
|
|
1635
1622
|
# A shortcut method that simplifies the various service control methods.
|
|
@@ -1637,17 +1624,17 @@ module Win32
|
|
|
1637
1624
|
def self.send_signal(service, host, service_signal, control_signal)
|
|
1638
1625
|
handle_scm = OpenSCManager(host, nil, SC_MANAGER_CONNECT)
|
|
1639
1626
|
|
|
1640
|
-
FFI.raise_windows_error(
|
|
1627
|
+
FFI.raise_windows_error("OpenSCManager") if handle_scm == 0
|
|
1641
1628
|
|
|
1642
1629
|
begin
|
|
1643
1630
|
handle_scs = OpenService(handle_scm, service, service_signal)
|
|
1644
1631
|
|
|
1645
|
-
FFI.raise_windows_error(
|
|
1632
|
+
FFI.raise_windows_error("OpenService") if handle_scs == 0
|
|
1646
1633
|
|
|
1647
1634
|
status = SERVICE_STATUS.new
|
|
1648
1635
|
|
|
1649
1636
|
unless ControlService(handle_scs, control_signal, status)
|
|
1650
|
-
FFI.raise_windows_error(
|
|
1637
|
+
FFI.raise_windows_error("ControlService")
|
|
1651
1638
|
end
|
|
1652
1639
|
ensure
|
|
1653
1640
|
close_service_handle(handle_scs)
|