win32-service 0.8.7 → 0.8.8

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c2d9406b19292d6d66131600aa2e18a15d193da
4
- data.tar.gz: cf2ba8abfcfe003ad3f00e44887ab195b0439115
3
+ metadata.gz: 8c9e7a6cfd6aa6f113daf315e64979fb66c9c83b
4
+ data.tar.gz: bc7920b71189a326bfd7b2b6e9affd2bd1fb1ded
5
5
  SHA512:
6
- metadata.gz: 13bb69b43beacc04a54bdc387b4fa78604bd48c147be9ead2c50958216d26ebac91161f64a62fc19262e01d409c2523969437439f4c676ccd5b68acc27f46f10
7
- data.tar.gz: f08fc1b91207ae51e1399580b54b275ad36baf048b66ccf93009568e4f18072593c7acb3b008d76a528a77e79959cd2523b9122438cc4bbb32dfbd2b7f076cd1
6
+ metadata.gz: c3bca8887a30ced151972c81d62d0d724ba3954b62b7ce435b02053ce91d674602a2d274955992c6b4a28d751ce574da8f2ffb6aa5045e27b0b6d0cb345fa5fe
7
+ data.tar.gz: 8ad98044dd9fdee7917a2267715d0ecbd1b37d946525fba1a340391e877a6f340464fef6c31b4ad93f70e020e126ab5f986bc4830050d1bc66c366a2d9f59bda
Binary file
@@ -0,0 +1,2 @@
1
+ ��~�ՒG/n�"J�+�r�״]�θ
2
+ �#i"rty�\��TL#:��v
data/CHANGES CHANGED
@@ -1,3 +1,24 @@
1
+ == 0.8.8 - 24-Jun-2016
2
+ * Fixed the function prototypes for CreateEvent and AdjustTokenPrivileges
3
+ where I was using :bool instead of :int.
4
+ * Updated the various FFI module wrapper names so that they're more distinctly
5
+ namespaced. Avoids a clash with the win32-eventlog gem, and possibly others.
6
+ * Discovered more places where QueryServiceConfig2 could fail while attempting
7
+ to get failure actions and delayed auto start info. Instead of failing,
8
+ these now set their respective data to nil.
9
+ * A timeout value in our main observer thread was increased to potentially
10
+ improve performance. Feedback welcome.
11
+ * This gem is now signed.
12
+ * Added the win32-service.rb and win32-daemon.rb files for convenience.
13
+ * Use require_relative internally.
14
+ * Added win32-security as a development dependency. It was already being used
15
+ for tests but now it's actually part of the gemspec.
16
+ * Many tests are now skipped unless run with administrative privileges, either
17
+ because they require it, or because they otherwise take too long.
18
+ * Gem related tasks in the Rakefile now assume Rubygems 2.x.
19
+ * Added an appveyor.yml file.
20
+ * The DemoDaemon example will create C:/Tmp if it doesn't already exist.
21
+
1
22
  == 0.8.7 - 14-Jul-2014
2
23
  * Fixed a bug in the SERVICE_DELAYED_AUTO_START_INFO struct. It now returns 0
3
24
  or 1, though it still accepts true or false as arguments. Thanks go to
data/MANIFEST CHANGED
@@ -3,11 +3,14 @@
3
3
  * README
4
4
  * Rakefile
5
5
  * win32-service.gemspec
6
+ * certs/djberg96_pub.pem
6
7
  * doc/daemon.txt
7
8
  * doc/service.txt
8
9
  * examples/demo_daemon.rb
9
10
  * examples/demo_daemon_ctl.rb
10
11
  * examples/demo_services.rb
12
+ * lib/win32-daemon.rb
13
+ * lib/win32-service.rb
11
14
  * lib/win32/service.rb
12
15
  * lib/win32/daemon.rb
13
16
  * test/test_win32_daemon.rb
data/README CHANGED
@@ -56,17 +56,11 @@
56
56
  Add service_session_change hook
57
57
 
58
58
  == Copyright
59
- (C) 2003-2014, Daniel J. Berger, All Rights Reserved
59
+ (C) 2003-2016, Daniel J. Berger, All Rights Reserved
60
60
 
61
61
  == License
62
62
  Artistic 2.0
63
63
 
64
- == Contributions
65
- Although this library is free, please consider having your company
66
- setup a gittip if used by your company professionally.
67
-
68
- http://www.gittip.com/djberg96/
69
-
70
64
  == Warranty
71
65
  This package is provided "as is" and without any express or
72
66
  implied warranties, including, without limitation, the implied
data/Rakefile CHANGED
@@ -12,13 +12,10 @@ CLEAN.include(
12
12
  namespace 'gem' do
13
13
  desc "Create the win32-service gem"
14
14
  task :create => [:clean] do
15
+ require 'rubygems/package'
15
16
  spec = eval(IO.read('win32-service.gemspec'))
16
- if Gem::VERSION.to_f < 2.0
17
- Gem::Builder.new(spec).build
18
- else
19
- require 'rubygems/package'
20
- Gem::Package.build(spec)
21
- end
17
+ spec.signing_key = File.join(Dir.home, '.ssh', 'gem-private_key.pem')
18
+ Gem::Package.build(spec, true)
22
19
  end
23
20
 
24
21
  desc "Install the win32-service gem"
@@ -0,0 +1,48 @@
1
+ version: '{build}'
2
+ branches:
3
+ only:
4
+ - ffi
5
+ skip_tags: true
6
+ clone_depth: 10
7
+ environment:
8
+ matrix:
9
+ - ruby_version: 193
10
+ ruby_dir: 1.9.1
11
+ - ruby_version: 200
12
+ ruby_dir: 2.0.0
13
+ - ruby_version: 200-x64
14
+ ruby_dir: 2.0.0
15
+ - ruby_version: 21
16
+ ruby_dir: 2.1.0
17
+ - ruby_version: 21-x64
18
+ ruby_dir: 2.1.0
19
+ - ruby_version: 22
20
+ ruby_dir: 2.2.0
21
+ - ruby_version: 22-x64
22
+ ruby_dir: 2.2.0
23
+ install:
24
+ - ps: >-
25
+ $env:path = "C:\Ruby" + $env:ruby_version + "\bin;" + $env:path
26
+
27
+ $tpath = "C:\Ruby" + $env:ruby_version + "\lib\ruby\" + $env:ruby_dir + "\test"
28
+
29
+ if ((test-path $tpath) -eq $True){ rm -recurse -force $tpath }
30
+
31
+ gem update --system > $null
32
+
33
+ if ((gem query -i ffi) -eq $False){ gem install ffi --no-document }
34
+
35
+ if ((gem query -i win32-security) -eq $False){ gem install win32-security --no-document }
36
+
37
+ if ((gem query -i test-unit -v ">= 3.0") -eq $False){ gem install test-unit --no-document }
38
+ cache:
39
+ - C:\Ruby193\lib\ruby\gems\1.9.1
40
+ - C:\Ruby200\lib\ruby\gems\2.0.0
41
+ - C:\Ruby200-x64\lib\ruby\gems\2.0.0
42
+ - C:\Ruby21\lib\ruby\gems\2.1.0
43
+ - C:\Ruby21-x64\lib\ruby\gems\2.1.0
44
+ - C:\Ruby22\lib\ruby\gems\2.2.0
45
+ - C:\Ruby22-x64\lib\ruby\gems\2.2.0
46
+ build: off
47
+ test_script:
48
+ - cmd: rake
@@ -0,0 +1,21 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
3
+ cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
4
+ MB4XDTE1MDkwMjIwNDkxOFoXDTE2MDkwMTIwNDkxOFowPzERMA8GA1UEAwwIZGpi
5
+ ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
6
+ bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyTkvXqRp6hLs9eoJOS
7
+ Hmi8kRYbq9Vkf15/hMxJpotYMgJVHHWrmDcC5Dye2PbnXjTkKf266Zw0PtT9h+lI
8
+ S3ts9HO+vaCFSMwFFZmnWJSpQ3CNw2RcHxjWkk9yF7imEM8Kz9ojhiDXzBetdV6M
9
+ gr0lV/alUr7TNVBDngbXEfTWscyXh1qd7xZ4EcOdsDktCe5G45N/o3662tPQvJsi
10
+ FOF0CM/KuBsa/HL1/eoEmF4B3EKIRfTHrQ3hu20Kv3RJ88QM4ec2+0dd97uX693O
11
+ zv6981fyEg+aXLkxrkViM/tz2qR2ZE0jPhHTREPYeMEgptRkTmWSKAuLVWrJEfgl
12
+ DtkCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFEwe
13
+ nn6bfJADmuIDiMSOzedOrL+xMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
14
+ bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
15
+ ggEBAHmNOCWoDVD75zHFueY0viwGDVP1BNGFC+yXcb7u2GlK+nEMCORqzURbYPf7
16
+ tL+/hzmePIRz7i30UM//64GI1NLv9jl7nIwjhPpXpf7/lu2I9hOTsvwSumb5UiKC
17
+ /sqBxI3sfj9pr79Wpv4MuikX1XPik7Ncb7NPsJPw06Lvyc3Hkg5X2XpPtLtS+Gr2
18
+ wKJnmzb5rIPS1cmsqv0M9LPWflzfwoZ/SpnmhagP+g05p8bRNKjZSA2iImM/GyYZ
19
+ EJYzxdPOrx2n6NYR3Hk+vHP0U7UBSveI6+qx+ndQYaeyCn+GRX2PKS9h66YF/Q1V
20
+ tGSHgAmcLlkdGgan182qsE/4kKM=
21
+ -----END CERTIFICATE-----
@@ -127,7 +127,7 @@ Daemon::IDLE
127
127
  setup your own Daemon.
128
128
 
129
129
  = Known Bugs
130
- None known. Please report any bugs you find on the Bug tracker at
130
+ None known. Please report any bugs you find on the issue tracker at
131
131
  https//github.com/djberg96/win32-service
132
132
 
133
133
  = Future Plans
@@ -142,7 +142,7 @@ Daemon::IDLE
142
142
  his patch that solved service responsiveness issues.
143
143
 
144
144
  = Copyright
145
- (C) 2003-2013 Daniel J. Berger, All Rights Reserved
145
+ (C) 2003-2016 Daniel J. Berger, All Rights Reserved
146
146
 
147
147
  = License
148
148
  Artistic 2.0
@@ -2,7 +2,7 @@
2
2
  An interface for MS Windows Services.
3
3
 
4
4
  = Prerequisites
5
- FFI 1.0 or later
5
+ ffi 1.0 or later
6
6
 
7
7
  This library is only supported for the Windows NT family of operating
8
8
  systems, e.g. 2000, XP, 2003, etc. It is NOT supported (and won't
@@ -351,7 +351,7 @@ Service::ERROR_CRITICAL
351
351
  Add ability to create or modify service failure actions.
352
352
 
353
353
  = Copyright
354
- (C) 2003-2013, Daniel J. Berger, All Rights Reserved
354
+ (C) 2003-2016, Daniel J. Berger, All Rights Reserved
355
355
 
356
356
  = Warranty
357
357
  This package is provided "as is" and without any express or
@@ -12,6 +12,7 @@ begin
12
12
  # timeout error when you try to start it.
13
13
  #
14
14
  def service_init
15
+ Dir.mkdir("C:/Tmp") unless File.exist?("C:/Tmp")
15
16
  10.times{ |i|
16
17
  File.open(LOG_FILE , 'a'){ |f| f.puts("#{i}") }
17
18
  sleep 1
@@ -2,7 +2,7 @@
2
2
  # demo_daemon_ctl.rb
3
3
  #
4
4
  # This is a command line script for installing and/or running a small
5
- # Ruby program as a service. The service will simply write a small bit
5
+ # Ruby program as a service. The service will simply write a small bit
6
6
  # of text to a file every 20 seconds. It will also write some text to the
7
7
  # file during the initialization (service_init) step.
8
8
  #
@@ -10,7 +10,8 @@
10
10
  # of the service_init hook, so don't be surprised if you see "one moment,
11
11
  # start pending" about 10 times on the command line.
12
12
  #
13
- # The file in question is C:\test.log. Feel free to delete it when finished.
13
+ # The file in question is C:\Tmp\win32_daemon_test.log. Feel free to delete
14
+ # it when you're finished.
14
15
  #
15
16
  # To run the service, you must install it first.
16
17
  #
@@ -0,0 +1 @@
1
+ require_relative 'win32/daemon'
@@ -0,0 +1 @@
1
+ require_relative 'win32/service'
@@ -1,9 +1,7 @@
1
- require File.join(File.dirname(__FILE__), 'windows', 'helper')
2
- require File.join(File.dirname(__FILE__), 'windows', 'constants')
3
- require File.join(File.dirname(__FILE__), 'windows', 'structs')
4
- require File.join(File.dirname(__FILE__), 'windows', 'functions')
5
-
6
- require 'ffi'
1
+ require_relative 'windows/helper'
2
+ require_relative 'windows/constants'
3
+ require_relative 'windows/structs'
4
+ require_relative 'windows/functions'
7
5
 
8
6
  # The Win32 module serves as a namespace only.
9
7
  module Win32
@@ -11,14 +9,14 @@ module Win32
11
9
  # The Daemon class
12
10
  class Daemon
13
11
  include Windows::ServiceConstants
14
- include Windows::Structs
15
- include Windows::Functions
12
+ include Windows::ServiceStructs
13
+ include Windows::ServiceFunctions
16
14
 
17
- extend Windows::Structs
18
- extend Windows::Functions
15
+ extend Windows::ServiceStructs
16
+ extend Windows::ServiceFunctions
19
17
 
20
18
  # The version of this library
21
- VERSION = '0.8.6'
19
+ VERSION = '0.8.8'
22
20
 
23
21
  private
24
22
 
@@ -240,21 +238,21 @@ module Win32
240
238
  service_init() if respond_to?('service_init')
241
239
 
242
240
  # Create the event to signal the service to start.
243
- @@hStartEvent = CreateEvent(nil, true, false, nil)
241
+ @@hStartEvent = CreateEvent(nil, 1, 0, nil)
244
242
 
245
243
  if @@hStartEvent == 0
246
244
  raise SystemCallError.new('CreateEvent', FFI.errno)
247
245
  end
248
246
 
249
247
  # Create the event to signal the service to stop.
250
- @@hStopEvent = CreateEvent(nil, true, false, nil)
248
+ @@hStopEvent = CreateEvent(nil, 1, 0, nil)
251
249
 
252
250
  if @@hStopEvent == 0
253
251
  raise SystemCallError.new('CreateEvent', FFI.errno)
254
252
  end
255
253
 
256
254
  # Create the event to signal the service that stop has completed
257
- @@hStopCompletedEvent = CreateEvent(nil, true, false, nil)
255
+ @@hStopCompletedEvent = CreateEvent(nil, 1, 0, nil)
258
256
 
259
257
  if @@hStopCompletedEvent == 0
260
258
  raise SystemCallError.new('CreateEvent', FFI.errno)
@@ -270,7 +268,7 @@ module Win32
270
268
  events.put_pointer(0, FFI::Pointer.new(hThread))
271
269
  events.put_pointer(FFI::Pointer.size, FFI::Pointer.new(@@hStartEvent))
272
270
 
273
- while ((index = WaitForMultipleObjects(2, events, false, 1000)) == WAIT_TIMEOUT) do
271
+ while ((index = WaitForMultipleObjects(2, events, 0, 1000)) == WAIT_TIMEOUT) do
274
272
  end
275
273
 
276
274
  if index == WAIT_FAILED
@@ -284,7 +282,7 @@ module Win32
284
282
 
285
283
  thr = Thread.new do
286
284
  begin
287
- while(WaitForSingleObject(@@hStopEvent, 10) == WAIT_TIMEOUT)
285
+ while(WaitForSingleObject(@@hStopEvent, 1000) == WAIT_TIMEOUT)
288
286
  # Check to see if anything interesting has been signaled
289
287
  case @@waiting_control_code
290
288
  when SERVICE_CONTROL_PAUSE
@@ -10,14 +10,14 @@ module Win32
10
10
  # creating, starting, configuring or deleting services.
11
11
  class Service
12
12
  include Windows::ServiceConstants
13
- include Windows::Structs
14
- include Windows::Functions
13
+ include Windows::ServiceStructs
14
+ include Windows::ServiceFunctions
15
15
 
16
- extend Windows::Structs
17
- extend Windows::Functions
16
+ extend Windows::ServiceStructs
17
+ extend Windows::ServiceFunctions
18
18
 
19
19
  # The version of the win32-service library
20
- VERSION = '0.8.7'
20
+ VERSION = '0.8.8'
21
21
 
22
22
  # SCM security and access rights
23
23
 
@@ -1085,22 +1085,24 @@ module Win32
1085
1085
  end
1086
1086
  rescue
1087
1087
  # While being annoying, not being able to get a description is not exceptional
1088
- warn "WARNING: Failed to retreive description for the #{service_name} service."
1088
+ warn "WARNING: Failed to retrieve description for the #{service_name} service."
1089
1089
  description = ''
1090
1090
  end
1091
1091
 
1092
- delayed_start_buf = get_config2_info(handle_scs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO)
1093
-
1094
- if delayed_start_buf.is_a?(FFI::MemoryPointer)
1095
- delayed_start_info = SERVICE_DELAYED_AUTO_START_INFO.new(delayed_start_buf)
1096
- delayed_start = delayed_start_info[:fDelayedAutostart]
1097
- else
1098
- delayed_start = false
1092
+ begin
1093
+ delayed_start_buf = get_config2_info(handle_scs, SERVICE_CONFIG_DELAYED_AUTO_START_INFO)
1094
+ if delayed_start_buf.is_a?(FFI::MemoryPointer)
1095
+ delayed_start_info = SERVICE_DELAYED_AUTO_START_INFO.new(delayed_start_buf)
1096
+ delayed_start = delayed_start_info[:fDelayedAutostart]
1097
+ else
1098
+ delayed_start = false
1099
+ end
1100
+ rescue
1101
+ warn "WARNING: Unable to get delayed auto start information for the #{service_name} service"
1102
+ delayed_start = nil
1099
1103
  end
1100
1104
  else
1101
- msg = "WARNING: The registry entry for the #{service_name} "
1102
- msg += "service could not be found."
1103
- warn msg
1105
+ warn "WARNING: The registry entry for the #{service_name} service could not be found"
1104
1106
 
1105
1107
  binary_path = nil
1106
1108
  load_order = nil
@@ -1112,41 +1114,49 @@ module Win32
1112
1114
  description = nil
1113
1115
  end
1114
1116
 
1115
- buf2 = get_config2_info(handle_scs, SERVICE_CONFIG_FAILURE_ACTIONS)
1117
+ begin
1118
+ buf2 = get_config2_info(handle_scs, SERVICE_CONFIG_FAILURE_ACTIONS)
1116
1119
 
1117
- if buf2.is_a?(FFI::MemoryPointer)
1118
- fail_struct = SERVICE_FAILURE_ACTIONS.new(buf2)
1120
+ if buf2.is_a?(FFI::MemoryPointer)
1121
+ fail_struct = SERVICE_FAILURE_ACTIONS.new(buf2)
1119
1122
 
1120
- reset_period = fail_struct[:dwResetPeriod]
1121
- num_actions = fail_struct[:cActions]
1123
+ reset_period = fail_struct[:dwResetPeriod]
1124
+ num_actions = fail_struct[:cActions]
1122
1125
 
1123
- if fail_struct[:lpRebootMsg].null?
1124
- reboot_msg = nil
1125
- else
1126
- reboot_msg = fail_struct[:lpRebootMsg].read_string
1127
- end
1126
+ if fail_struct[:lpRebootMsg].null?
1127
+ reboot_msg = nil
1128
+ else
1129
+ reboot_msg = fail_struct[:lpRebootMsg].read_string
1130
+ end
1128
1131
 
1129
- if fail_struct[:lpCommand].null?
1130
- command = nil
1131
- else
1132
- command = fail_struct[:lpCommand].read_string
1133
- end
1132
+ if fail_struct[:lpCommand].null?
1133
+ command = nil
1134
+ else
1135
+ command = fail_struct[:lpCommand].read_string
1136
+ end
1134
1137
 
1135
- actions = nil
1138
+ actions = nil
1136
1139
 
1137
- if num_actions > 0
1138
- action_ptr = fail_struct[:lpsaActions]
1140
+ if num_actions > 0
1141
+ action_ptr = fail_struct[:lpsaActions]
1139
1142
 
1140
- actions = {}
1143
+ actions = {}
1141
1144
 
1142
- num_actions.times{ |n|
1143
- sc_action = SC_ACTION.new(action_ptr[n])
1144
- delay = sc_action[:Delay]
1145
- action_type = get_action_type(sc_action[:Type])
1146
- actions[n+1] = {:action_type => action_type, :delay => delay}
1147
- }
1145
+ num_actions.times{ |n|
1146
+ sc_action = SC_ACTION.new(action_ptr[n])
1147
+ delay = sc_action[:Delay]
1148
+ action_type = get_action_type(sc_action[:Type])
1149
+ actions[n+1] = {:action_type => action_type, :delay => delay}
1150
+ }
1151
+ end
1152
+ else
1153
+ reset_period = nil
1154
+ reboot_msg = nil
1155
+ command = nil
1156
+ actions = nil
1148
1157
  end
1149
- else
1158
+ rescue
1159
+ warn "WARNING: Unable to retrieve failure actions for the #{service_name} service"
1150
1160
  reset_period = nil
1151
1161
  reboot_msg = nil
1152
1162
  command = nil
@@ -1242,7 +1252,7 @@ module Win32
1242
1252
  # Enable shutdown privilege in access token of this process
1243
1253
  bool = AdjustTokenPrivileges(
1244
1254
  token_handle,
1245
- false,
1255
+ 0,
1246
1256
  tkp,
1247
1257
  tkp.size,
1248
1258
  nil,
@@ -1,7 +1,7 @@
1
1
  require 'ffi'
2
2
 
3
3
  module Windows
4
- module Functions
4
+ module ServiceFunctions
5
5
  extend FFI::Library
6
6
 
7
7
  # Make FFI functions private
@@ -22,7 +22,7 @@ module Windows
22
22
  ffi_lib :kernel32
23
23
 
24
24
  attach_pfunc :CloseHandle, [:handle], :bool
25
- attach_pfunc :CreateEvent, :CreateEventA, [:ptr, :bool, :bool, :str], :handle
25
+ attach_pfunc :CreateEvent, :CreateEventA, [:ptr, :int, :int, :str], :handle
26
26
  attach_pfunc :CreateThread, [:ptr, :size_t, :ptr, :ptr, :dword, :ptr], :handle, :blocking => true
27
27
  attach_pfunc :EnterCriticalSection, [:ptr], :void
28
28
  attach_pfunc :FormatMessage, :FormatMessageA, [:ulong, :ptr, :ulong, :ulong, :str, :ulong, :ptr], :ulong
@@ -31,13 +31,13 @@ module Windows
31
31
  attach_pfunc :LeaveCriticalSection, [:ptr], :void
32
32
  attach_pfunc :SetEvent, [:handle], :bool
33
33
  attach_pfunc :WaitForSingleObject, [:handle, :dword], :dword, :blocking => true
34
- attach_pfunc :WaitForMultipleObjects, [:dword, :ptr, :bool, :dword], :dword
34
+ attach_pfunc :WaitForMultipleObjects, [:dword, :ptr, :int, :dword], :dword
35
35
 
36
36
  ffi_lib :advapi32
37
37
 
38
38
  callback :handler_ex, [:ulong, :ulong, :ptr, :ptr], :void
39
39
 
40
- attach_pfunc :AdjustTokenPrivileges, [:handle, :bool, :ptr, :dword, :ptr, :ptr], :bool
40
+ attach_pfunc :AdjustTokenPrivileges, [:handle, :int, :ptr, :dword, :ptr, :ptr], :bool
41
41
  attach_pfunc :CloseServiceHandle, [:handle], :bool
42
42
 
43
43
  attach_pfunc :ChangeServiceConfig, :ChangeServiceConfigA,
@@ -1,7 +1,7 @@
1
1
  require 'ffi'
2
2
 
3
3
  module Windows
4
- module Structs
4
+ module ServiceStructs
5
5
  extend FFI::Library
6
6
 
7
7
  typedef :ulong, :dword
@@ -17,7 +17,7 @@ class TC_Daemon < Test::Unit::TestCase
17
17
  end
18
18
 
19
19
  test "version number is set properly" do
20
- assert_equal('0.8.6', Daemon::VERSION)
20
+ assert_equal('0.8.8', Daemon::VERSION)
21
21
  end
22
22
 
23
23
  test "constructor basic functionality" do
@@ -1,7 +1,9 @@
1
1
  ##########################################################################
2
2
  # test_win32_service.rb
3
3
  #
4
- # Tests for the Win32::Service class.
4
+ # Tests for the Win32::Service class. Some tests are skipped unless
5
+ # run with admin privileges either because they are somewhat invasive,
6
+ # or because they take too long.
5
7
  ##########################################################################
6
8
  require 'test-unit'
7
9
  require 'win32/security'
@@ -20,29 +22,39 @@ class TC_Win32_Service < Test::Unit::TestCase
20
22
  @service_name = 'stisvc'
21
23
  @service_stat = nil
22
24
  @services = []
25
+ @elevated = Win32::Security.elevated_security?
23
26
 
24
27
  @singleton_methods = Win32::Service.methods.map{ |m| m.to_s }
25
28
  @instance_methods = Win32::Service.instance_methods.map{ |m| m.to_s }
26
29
  end
27
30
 
31
+ def omit_unless_elevated
32
+ omit_unless(@elevated, "Skipped unless run with admin privileges")
33
+ end
34
+
28
35
  def start_service(service)
29
36
  status = Win32::Service.status(@service_name).current_state
30
- if status == 'paused'
31
- Win32::Service.resume(service)
32
- else
33
- unless ['running', 'start pending'].include?(status)
34
- Win32::Service.start(service)
37
+
38
+ if @elevated
39
+ if status == 'paused'
40
+ Win32::Service.resume(service)
41
+ else
42
+ unless ['running', 'start pending'].include?(status)
43
+ Win32::Service.start(service)
44
+ end
35
45
  end
46
+ wait_for_status('running')
36
47
  end
37
- wait_for_status('running')
38
48
  end
39
49
 
40
50
  def stop_service(service)
41
51
  status = Win32::Service.status(@service_name).current_state
42
- unless ['stopped', 'stop pending'].include?(status)
43
- Win32::Service.stop(service)
52
+ if @elevated
53
+ unless ['stopped', 'stop pending'].include?(status)
54
+ Win32::Service.stop(service)
55
+ end
56
+ wait_for_status('stopped')
44
57
  end
45
- wait_for_status('stopped')
46
58
  end
47
59
 
48
60
  # Helper method that waits for a status to change its state since state
@@ -52,14 +64,23 @@ class TC_Win32_Service < Test::Unit::TestCase
52
64
  end
53
65
 
54
66
  test "version number is expected value" do
55
- assert_equal('0.8.7', Win32::Service::VERSION)
67
+ assert_equal('0.8.8', Win32::Service::VERSION)
56
68
  end
57
69
 
58
70
  test "services basic functionality" do
59
71
  assert_respond_to(Win32::Service, :services)
72
+ end
73
+
74
+ test "services with no arguments works as expected" do
60
75
  assert_nothing_raised{ Win32::Service.services }
61
- assert_nothing_raised{ Win32::Service.services(nil) }
62
- assert_nothing_raised{ Win32::Service.services(nil, 'network') }
76
+ end
77
+
78
+ test "services with explicit host works as expected" do
79
+ assert_nothing_raised{ Win32::Service.services(@@host) }
80
+ end
81
+
82
+ test "services with explicit host and group works as expected" do
83
+ assert_nothing_raised{ Win32::Service.services(@@host, 'network') }
63
84
  end
64
85
 
65
86
  test "services method returns an array without a block" do
@@ -87,6 +108,7 @@ class TC_Win32_Service < Test::Unit::TestCase
87
108
  end
88
109
 
89
110
  test "a valid hostname must be provided or an error is raised" do
111
+ omit_unless_elevated
90
112
  assert_raise(SystemCallError){ Win32::Service.services('bogus') }
91
113
  end
92
114
 
@@ -99,11 +121,12 @@ class TC_Win32_Service < Test::Unit::TestCase
99
121
  end
100
122
 
101
123
  test "delete method raises an error if a bogus service name is provided" do
102
- omit_unless(@@elevated, "Skipped unless run with admin privileges")
124
+ omit_unless_elevated
103
125
  assert_raise(SystemCallError){ Win32::Service.delete('bogus') }
104
126
  end
105
127
 
106
128
  test "delete method raises an error if a bogus host name is provided" do
129
+ omit_unless_elevated
107
130
  assert_raise(SystemCallError){ Win32::Service.delete('bogus', 'bogus') }
108
131
  end
109
132
 
@@ -120,7 +143,7 @@ class TC_Win32_Service < Test::Unit::TestCase
120
143
  end
121
144
 
122
145
  test "pause and resume work as expected" do
123
- omit_unless(@@elevated, "Skipped unless run with admin privileges")
146
+ omit_unless_elevated
124
147
  start_service(@service_name)
125
148
 
126
149
  assert_nothing_raised{ Win32::Service.pause(@service_name) }
@@ -131,7 +154,7 @@ class TC_Win32_Service < Test::Unit::TestCase
131
154
  end
132
155
 
133
156
  test "pausing an already paused service is harmless" do
134
- omit_unless(@@elevated, "Skipped unless run with admin privileges")
157
+ omit_unless_elevated
135
158
  start_service(@service_name)
136
159
 
137
160
  assert_nothing_raised{ Win32::Service.pause(@service_name) }
@@ -148,6 +171,7 @@ class TC_Win32_Service < Test::Unit::TestCase
148
171
  end
149
172
 
150
173
  test "pausing a service on an unrecognized host raises an error" do
174
+ omit_unless_elevated
151
175
  assert_raise(SystemCallError){ Win32::Service.pause('W32Time', 'bogus') }
152
176
  end
153
177
 
@@ -164,6 +188,7 @@ class TC_Win32_Service < Test::Unit::TestCase
164
188
  end
165
189
 
166
190
  test "resume method with an unrecognized host name raises an error" do
191
+ omit_unless_elevated
167
192
  assert_raise(SystemCallError){ Win32::Service.resume('W32Time', 'bogus') }
168
193
  end
169
194
 
@@ -180,7 +205,7 @@ class TC_Win32_Service < Test::Unit::TestCase
180
205
  end
181
206
 
182
207
  test "stop and start methods work as expected" do
183
- omit_unless(@@elevated, "Skipped unless run with admin privileges")
208
+ omit_unless_elevated
184
209
  start_service(@service_name)
185
210
 
186
211
  assert_nothing_raised{ Win32::Service.stop(@service_name) }
@@ -191,7 +216,7 @@ class TC_Win32_Service < Test::Unit::TestCase
191
216
  end
192
217
 
193
218
  test "attempting to stop a stopped service raises an error" do
194
- omit_unless(@@elevated, "Skipped unless run with admin privileges")
219
+ omit_unless_elevated
195
220
  start_service(@service_name)
196
221
 
197
222
  assert_nothing_raised{ Win32::Service.stop(@service_name) }
@@ -210,6 +235,7 @@ class TC_Win32_Service < Test::Unit::TestCase
210
235
  end
211
236
 
212
237
  test "stop method raises an error if the host is unrecognized" do
238
+ omit_unless_elevated
213
239
  assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
214
240
  end
215
241
 
@@ -222,7 +248,7 @@ class TC_Win32_Service < Test::Unit::TestCase
222
248
  end
223
249
 
224
250
  test "attempting to start a running service raises an error" do
225
- omit_unless(@@elevated, "Skipped unless run with admin privileges")
251
+ omit_unless_elevated
226
252
  start_service(@service_name)
227
253
  assert_raise(SystemCallError){ Win32::Service.start(@service_name) }
228
254
  end
@@ -232,6 +258,7 @@ class TC_Win32_Service < Test::Unit::TestCase
232
258
  end
233
259
 
234
260
  test "attempting to start a service on an unknown host raises an error" do
261
+ omit_unless_elevated
235
262
  assert_raise(SystemCallError){ Win32::Service.start('bogus', 'bogus') }
236
263
  end
237
264
 
@@ -244,6 +271,7 @@ class TC_Win32_Service < Test::Unit::TestCase
244
271
  end
245
272
 
246
273
  test "stop raises an error with an unrecognized host" do
274
+ omit_unless_elevated
247
275
  assert_raise(SystemCallError){ Win32::Service.stop('W32Time', 'bogus') }
248
276
  end
249
277
 
@@ -281,6 +309,7 @@ class TC_Win32_Service < Test::Unit::TestCase
281
309
  end
282
310
 
283
311
  test "get_service_name raises an error if a bogus host is provided" do
312
+ omit_unless_elevated
284
313
  assert_raise(SystemCallError){ Win32::Service.get_service_name('foo', 'bogus') }
285
314
  end
286
315
 
@@ -312,6 +341,7 @@ class TC_Win32_Service < Test::Unit::TestCase
312
341
  end
313
342
 
314
343
  test "get_display_name raises an error if a bad host name is provided" do
344
+ omit_unless_elevated
315
345
  assert_raise(SystemCallError){ Win32::Service.get_display_name('W32Time', 'bogus') }
316
346
  end
317
347
 
@@ -335,9 +365,8 @@ class TC_Win32_Service < Test::Unit::TestCase
335
365
  end
336
366
 
337
367
  test "exists method raises an error if a bogus host is passed" do
338
- assert_raises(SystemCallError){
339
- Win32::Service.exists?('foo', 'bogushost')
340
- }
368
+ omit_unless_elevated
369
+ assert_raises(SystemCallError){ Win32::Service.exists?('foo', 'bogus') }
341
370
  end
342
371
 
343
372
  test "exists method only accepts up to two arguments" do
@@ -424,12 +453,14 @@ class TC_Win32_Service < Test::Unit::TestCase
424
453
  @@host = nil
425
454
  status = Win32::Service.status(@@service_name).current_state
426
455
 
427
- if status == 'paused'
428
- Win32::Service.resume(@@service_name)
429
- end
456
+ if @elevated
457
+ if status == 'paused'
458
+ Win32::Service.resume(@@service_name)
459
+ end
430
460
 
431
- unless ['running', 'start pending'].include?(status)
432
- Win32::Service.start(@@service_name)
461
+ unless ['running', 'start pending'].include?(status)
462
+ Win32::Service.start(@@service_name)
463
+ end
433
464
  end
434
465
 
435
466
  @@elevated = nil
@@ -4,6 +4,7 @@
4
4
  # Test suite that validates the Service.configure method.
5
5
  #######################################################################
6
6
  require 'test-unit'
7
+ require 'win32/security'
7
8
  require 'win32/service'
8
9
 
9
10
  class TC_Win32_Service_Configure < Test::Unit::TestCase
@@ -11,10 +12,12 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
11
12
  @@service = "notepad_service"
12
13
  @@command = "C:\\windows\\system32\\notepad.exe"
13
14
 
14
- Win32::Service.new(
15
- :service_name => @@service,
16
- :binary_path_name => @@command
17
- )
15
+ if Win32::Security.elevated_security?
16
+ Win32::Service.new(
17
+ :service_name => @@service,
18
+ :binary_path_name => @@command
19
+ )
20
+ end
18
21
  end
19
22
 
20
23
  def config_info
@@ -39,7 +42,8 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
39
42
  end
40
43
 
41
44
  def setup
42
- @info = Win32::Service.config_info(@@service)
45
+ @elevated = Win32::Security.elevated_security?
46
+ @info = Win32::Service.config_info(@@service) if @elevated
43
47
  end
44
48
 
45
49
  test "configure method is defined" do
@@ -47,24 +51,28 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
47
51
  end
48
52
 
49
53
  test "configuring the service type works as expected" do
54
+ omit_unless(@elevated)
50
55
  assert_equal('own process', config_info.service_type)
51
56
  service_configure(:service_type => Win32::Service::WIN32_SHARE_PROCESS)
52
57
  assert_equal('share process', config_info.service_type)
53
58
  end
54
59
 
55
60
  test "configuring the description works as expected" do
61
+ omit_unless(@elevated)
56
62
  assert_equal('', full_info.description)
57
63
  service_configure(:description => 'test service')
58
64
  assert_equal('test service', full_info.description)
59
65
  end
60
66
 
61
67
  test "configuring the start type works as expected" do
68
+ omit_unless(@elevated)
62
69
  assert_equal('demand start', config_info.start_type)
63
70
  service_configure(:start_type => Win32::Service::DISABLED)
64
71
  assert_equal('disabled', config_info.start_type)
65
72
  end
66
73
 
67
74
  test "service start can be delayed" do
75
+ omit_unless(@elevated)
68
76
  service_configure(:start_type => Win32::Service::AUTO_START, :delayed_start => true)
69
77
  assert_equal(1, full_info.delayed_start)
70
78
  end
@@ -89,10 +97,13 @@ class TC_Win32_Service_Configure < Test::Unit::TestCase
89
97
 
90
98
  def teardown
91
99
  @info = nil
100
+ @elevated = nil
92
101
  end
93
102
 
94
103
  def self.shutdown
95
- Win32::Service.delete(@@service) if Win32::Service.exists?(@@service)
104
+ if Win32::Service.exists?(@@service) && Win32::Security.elevated_security?
105
+ Win32::Service.delete(@@service)
106
+ end
96
107
  @@service = nil
97
108
  @@command = nil
98
109
  end
@@ -5,6 +5,7 @@
5
5
  # a dummy (notepad) service. It won't actually run of course.
6
6
  ########################################################################
7
7
  require 'test-unit'
8
+ require 'win32/security'
8
9
  require 'win32/service'
9
10
 
10
11
  class TC_Win32_Service_Create < Test::Unit::TestCase
@@ -13,28 +14,34 @@ class TC_Win32_Service_Create < Test::Unit::TestCase
13
14
  @@service2 = "notepad_service2"
14
15
  @@command = "C:\\windows\\system32\\notepad.exe"
15
16
 
16
- Win32::Service.new(
17
- :service_name => @@service1,
18
- :binary_path_name => @@command
19
- )
20
-
21
- Win32::Service.new(
22
- :service_name => @@service2,
23
- :display_name => 'Notepad Test',
24
- :desired_access => Win32::Service::ALL_ACCESS,
25
- :service_type => Win32::Service::WIN32_OWN_PROCESS,
26
- :start_type => Win32::Service::DISABLED,
27
- :error_control => Win32::Service::ERROR_IGNORE,
28
- :binary_path_name => @@command,
29
- :load_order_group => 'Network',
30
- :dependencies => 'W32Time',
31
- :description => 'Test service. Please delete me'
32
- )
17
+ if Win32::Security.elevated_security?
18
+ Win32::Service.new(
19
+ :service_name => @@service1,
20
+ :binary_path_name => @@command
21
+ )
22
+
23
+ Win32::Service.new(
24
+ :service_name => @@service2,
25
+ :display_name => 'Notepad Test',
26
+ :desired_access => Win32::Service::ALL_ACCESS,
27
+ :service_type => Win32::Service::WIN32_OWN_PROCESS,
28
+ :start_type => Win32::Service::DISABLED,
29
+ :error_control => Win32::Service::ERROR_IGNORE,
30
+ :binary_path_name => @@command,
31
+ :load_order_group => 'Network',
32
+ :dependencies => 'W32Time',
33
+ :description => 'Test service. Please delete me'
34
+ )
35
+ end
33
36
  end
34
37
 
35
38
  def setup
36
- @info1 = Win32::Service.config_info(@@service1)
37
- @info2 = Win32::Service.config_info(@@service2)
39
+ @elevated = Win32::Security.elevated_security?
40
+
41
+ if @elevated
42
+ @info1 = Win32::Service.config_info(@@service1)
43
+ @info2 = Win32::Service.config_info(@@service2)
44
+ end
38
45
  end
39
46
 
40
47
  test "constructor basic functionality" do
@@ -48,48 +55,59 @@ class TC_Win32_Service_Create < Test::Unit::TestCase
48
55
  end
49
56
 
50
57
  test "ensure services were created in startup method" do
58
+ omit_unless(@elevated)
51
59
  notify "If this test fails then remaining results are meaningless."
52
60
  assert_true(Win32::Service.exists?(@@service1))
53
61
  assert_true(Win32::Service.exists?(@@service2))
54
62
  end
55
63
 
56
64
  test "expected service type configuration information" do
65
+ omit_unless(@elevated)
57
66
  assert_equal('own process', @info1.service_type)
58
67
  end
59
68
 
60
69
  test "expected start type configuration information" do
70
+ omit_unless(@elevated)
61
71
  assert_equal('demand start', @info1.start_type)
62
72
  end
63
73
 
64
74
  test "expected error control configuration information" do
75
+ omit_unless(@elevated)
65
76
  assert_equal('normal', @info1.error_control)
66
77
  end
67
78
 
68
79
  test "expected binary path name configuration information" do
80
+ omit_unless(@elevated)
69
81
  assert_equal(@@command, @info1.binary_path_name)
70
82
  end
71
83
 
72
84
  test "expected load order group configuration information" do
85
+ omit_unless(@elevated)
73
86
  assert_equal('', @info1.load_order_group)
74
87
  end
75
88
 
76
89
  test "expected tag id configuration information" do
90
+ omit_unless(@elevated)
77
91
  assert_equal(0, @info1.tag_id)
78
92
  end
79
93
 
80
94
  test "expected dependency configuration information" do
95
+ omit_unless(@elevated)
81
96
  assert_equal([], @info1.dependencies)
82
97
  end
83
98
 
84
99
  test "expected service start time configuration information" do
100
+ omit_unless(@elevated)
85
101
  assert_equal('LocalSystem', @info1.service_start_name)
86
102
  end
87
103
 
88
104
  test "expected display name configuration information" do
105
+ omit_unless(@elevated)
89
106
  assert_equal('notepad_service1', @info1.display_name)
90
107
  end
91
108
 
92
109
  test "configuration information options are set properly for service 2" do
110
+ omit_unless(@elevated)
93
111
  assert_equal('own process', @info2.service_type)
94
112
  assert_equal('disabled', @info2.start_type)
95
113
  assert_equal('ignore', @info2.error_control)
@@ -114,13 +132,19 @@ class TC_Win32_Service_Create < Test::Unit::TestCase
114
132
  end
115
133
 
116
134
  def teardown
117
- @info1 = nil
118
- @info2 = nil
135
+ if @elevated
136
+ @info1 = nil
137
+ @info2 = nil
138
+ end
139
+
140
+ @elevated = nil
119
141
  end
120
142
 
121
143
  def self.shutdown
122
- Win32::Service.delete(@@service1) if Win32::Service.exists?(@@service1)
123
- Win32::Service.delete(@@service2) if Win32::Service.exists?(@@service2)
144
+ if Win32::Security.elevated_security?
145
+ Win32::Service.delete(@@service1) if Win32::Service.exists?(@@service1)
146
+ Win32::Service.delete(@@service2) if Win32::Service.exists?(@@service2)
147
+ end
124
148
 
125
149
  @@service1 = nil
126
150
  @@service2 = nil
@@ -71,106 +71,107 @@ class TC_Win32_ServiceInfo_Struct < Test::Unit::TestCase
71
71
  ]
72
72
  end
73
73
 
74
- def test_service_info_info_service_name
74
+ test "service_name basic functionality" do
75
75
  assert_respond_to(@service_info, :service_name)
76
76
  assert_kind_of(String, @service_info.service_name)
77
77
  end
78
78
 
79
- def test_service_info_info_display_name
79
+ test "display_name basic functionality" do
80
80
  assert_respond_to(@service_info, :display_name)
81
81
  assert_kind_of(String, @service_info.display_name)
82
82
  end
83
83
 
84
- def test_service_info_info_service_type
84
+ test "service_type basic functionality" do
85
85
  assert_respond_to(@service_info, :service_type)
86
86
  assert(@types.include?(@service_info.service_type))
87
87
  end
88
88
 
89
- def test_service_info_current_state
89
+ test "current_state basic functionality" do
90
90
  assert_respond_to(@service_info, :current_state)
91
91
  assert(@states.include?(@service_info.current_state))
92
92
  end
93
93
 
94
- def test_service_info_controls_accepted
94
+ test "controls_accepted basic functionality" do
95
95
  assert_respond_to(@service_info, :controls_accepted)
96
96
  assert_kind_of(Array, @service_info.controls_accepted)
97
+ end
98
+
99
+ test "controls_accepted returns expected values" do
97
100
  assert_false(@service_info.controls_accepted.empty?)
98
- @service_info.controls_accepted.each{ |control|
99
- assert_true(@controls.include?(control))
100
- }
101
+ @service_info.controls_accepted.each{ |c| assert_true(@controls.include?(c)) }
101
102
  end
102
103
 
103
- def test_service_info_win32_exit_code
104
+ test "win32_exit_code basic functionality" do
104
105
  assert_respond_to(@service_info, :win32_exit_code)
105
106
  assert_kind_of(Fixnum, @service_info.win32_exit_code)
106
107
  end
107
108
 
108
- def test_service_info_service_specific_exit_code
109
+ test "service_specific_exit_code basic functionality" do
109
110
  assert_respond_to(@service_info, :service_specific_exit_code)
110
111
  assert_kind_of(Fixnum, @service_info.service_specific_exit_code)
111
112
  end
112
113
 
113
- def test_service_info_check_point
114
+ test "check_point basic functionality" do
114
115
  assert_respond_to(@service_info, :check_point)
115
116
  assert_kind_of(Fixnum, @service_info.check_point)
116
117
  end
117
118
 
118
- def test_service_info_wait_hint
119
+ test "wait_hint basic functionality" do
119
120
  assert_respond_to(@service_info, :wait_hint)
120
121
  assert_kind_of(Fixnum, @service_info.wait_hint)
121
122
  end
122
123
 
123
- def test_service_info_binary_path_name
124
+ test "binary_path_name basic functionality" do
124
125
  assert_respond_to(@service_info, :binary_path_name)
125
126
  assert_kind_of(String, @service_info.binary_path_name)
126
127
  end
127
128
 
128
- def test_service_info_start_type
129
+ test "start_type basic functionality" do
129
130
  assert_respond_to(@service_info, :start_type)
130
131
  assert(@start_types.include?(@service_info.start_type))
131
132
  end
132
133
 
133
- def test_service_info_error_control
134
+ test "error_control basic functionality" do
134
135
  assert_respond_to(@service_info, :error_control)
135
136
  assert(@error_controls.include?(@service_info.error_control))
136
137
  end
137
138
 
138
- def test_service_info_load_order_group
139
+ test "load_order_group basic functionality" do
139
140
  assert_respond_to(@service_info, :load_order_group)
140
141
  assert_kind_of(String, @service_info.load_order_group)
141
142
  end
142
143
 
143
- def test_service_info_tag_id
144
+ test "tag_id basic functionality" do
144
145
  assert_respond_to(@service_info, :tag_id)
145
146
  assert_kind_of(Fixnum, @service_info.tag_id)
146
147
  end
147
148
 
148
- def test_service_info_start_name
149
+ test "start_name basic functionality" do
149
150
  assert_respond_to(@service_info, :start_name)
150
151
  assert_kind_of(String, @service_info.start_name)
151
152
  end
152
153
 
153
- def test_service_info_dependencies
154
+ test "dependencies basic functionality" do
154
155
  assert_respond_to(@service_info, :dependencies)
155
156
  assert_kind_of(Array, @service_info.dependencies)
156
157
  end
157
158
 
158
- def test_service_info_description
159
+ test "description basic functionality" do
159
160
  assert_respond_to(@service_info, :description)
160
161
  assert_kind_of(String, @service_info.description)
161
162
  end
162
163
 
163
- def test_service_info_interactive
164
+ test "interactive basic functionality" do
164
165
  assert_respond_to(@service_info, :interactive)
165
166
  assert_boolean(@service_info.interactive)
166
167
  end
167
168
 
168
- def test_service_info_service_flags
169
+ test "service_flags basic functionality" do
169
170
  assert_respond_to(@service_info, :service_flags)
170
171
  assert([0,1].include?(@service_info.service_flags))
171
172
  end
172
173
 
173
- def test_service_info_delayed_start
174
+ test "delayed_start basic functionality" do
174
175
  assert_respond_to(@service_info, :delayed_start)
175
176
  assert([0,1].include?(@service_info.delayed_start))
176
177
  end
@@ -2,13 +2,14 @@ require 'rubygems'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'win32-service'
5
- spec.version = '0.8.7'
5
+ spec.version = '0.8.8'
6
6
  spec.authors = ['Daniel J. Berger', 'Park Heesob']
7
7
  spec.license = 'Artistic 2.0'
8
8
  spec.email = 'djberg96@gmail.com'
9
9
  spec.homepage = 'http://github.com/djberg96/win32-service'
10
10
  spec.summary = 'An interface for MS Windows services'
11
11
  spec.test_files = Dir['test/test*.rb']
12
+ spec.cert_chain = Dir['certs/*']
12
13
 
13
14
  spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
14
15
 
@@ -23,6 +24,7 @@ Gem::Specification.new do |spec|
23
24
  spec.add_dependency('ffi')
24
25
  spec.add_development_dependency('test-unit')
25
26
  spec.add_development_dependency('rake')
27
+ spec.add_development_dependency('win32-security')
26
28
 
27
29
  spec.description = <<-EOF
28
30
  The win32-service library provides a Ruby interface to services on
metadata CHANGED
@@ -1,15 +1,37 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.7
4
+ version: 0.8.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
8
8
  - Park Heesob
9
9
  autorequire:
10
10
  bindir: bin
11
- cert_chain: []
12
- date: 2015-07-15 00:00:00.000000000 Z
11
+ cert_chain:
12
+ - |
13
+ -----BEGIN CERTIFICATE-----
14
+ MIIDcDCCAligAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MREwDwYDVQQDDAhkamJl
15
+ cmc5NjEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYDY29t
16
+ MB4XDTE1MDkwMjIwNDkxOFoXDTE2MDkwMTIwNDkxOFowPzERMA8GA1UEAwwIZGpi
17
+ ZXJnOTYxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
18
+ bTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMyTkvXqRp6hLs9eoJOS
19
+ Hmi8kRYbq9Vkf15/hMxJpotYMgJVHHWrmDcC5Dye2PbnXjTkKf266Zw0PtT9h+lI
20
+ S3ts9HO+vaCFSMwFFZmnWJSpQ3CNw2RcHxjWkk9yF7imEM8Kz9ojhiDXzBetdV6M
21
+ gr0lV/alUr7TNVBDngbXEfTWscyXh1qd7xZ4EcOdsDktCe5G45N/o3662tPQvJsi
22
+ FOF0CM/KuBsa/HL1/eoEmF4B3EKIRfTHrQ3hu20Kv3RJ88QM4ec2+0dd97uX693O
23
+ zv6981fyEg+aXLkxrkViM/tz2qR2ZE0jPhHTREPYeMEgptRkTmWSKAuLVWrJEfgl
24
+ DtkCAwEAAaN3MHUwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0OBBYEFEwe
25
+ nn6bfJADmuIDiMSOzedOrL+xMB0GA1UdEQQWMBSBEmRqYmVyZzk2QGdtYWlsLmNv
26
+ bTAdBgNVHRIEFjAUgRJkamJlcmc5NkBnbWFpbC5jb20wDQYJKoZIhvcNAQEFBQAD
27
+ ggEBAHmNOCWoDVD75zHFueY0viwGDVP1BNGFC+yXcb7u2GlK+nEMCORqzURbYPf7
28
+ tL+/hzmePIRz7i30UM//64GI1NLv9jl7nIwjhPpXpf7/lu2I9hOTsvwSumb5UiKC
29
+ /sqBxI3sfj9pr79Wpv4MuikX1XPik7Ncb7NPsJPw06Lvyc3Hkg5X2XpPtLtS+Gr2
30
+ wKJnmzb5rIPS1cmsqv0M9LPWflzfwoZ/SpnmhagP+g05p8bRNKjZSA2iImM/GyYZ
31
+ EJYzxdPOrx2n6NYR3Hk+vHP0U7UBSveI6+qx+ndQYaeyCn+GRX2PKS9h66YF/Q1V
32
+ tGSHgAmcLlkdGgan182qsE/4kKM=
33
+ -----END CERTIFICATE-----
34
+ date: 2016-06-25 00:00:00.000000000 Z
13
35
  dependencies:
14
36
  - !ruby/object:Gem::Dependency
15
37
  name: ffi
@@ -53,6 +75,20 @@ dependencies:
53
75
  - - ">="
54
76
  - !ruby/object:Gem::Version
55
77
  version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: win32-security
80
+ requirement: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ type: :development
86
+ prerelease: false
87
+ version_requirements: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
56
92
  description: |2
57
93
  The win32-service library provides a Ruby interface to services on
58
94
  MS Windows. You can create new services, or control, configure and
@@ -70,21 +106,32 @@ extra_rdoc_files:
70
106
  - doc/service.txt
71
107
  - doc/daemon.txt
72
108
  files:
109
+ - appveyor.yml
110
+ - certs
111
+ - certs/djberg96_pub.pem
73
112
  - CHANGES
74
- - MANIFEST
75
- - README
76
- - Rakefile
113
+ - doc
77
114
  - doc/daemon.txt
78
115
  - doc/service.txt
116
+ - examples
79
117
  - examples/demo_daemon.rb
80
118
  - examples/demo_daemon_ctl.rb
81
119
  - examples/demo_services.rb
120
+ - lib
121
+ - lib/win32
82
122
  - lib/win32/daemon.rb
83
123
  - lib/win32/service.rb
124
+ - lib/win32/windows
84
125
  - lib/win32/windows/constants.rb
85
126
  - lib/win32/windows/functions.rb
86
127
  - lib/win32/windows/helper.rb
87
128
  - lib/win32/windows/structs.rb
129
+ - lib/win32-daemon.rb
130
+ - lib/win32-service.rb
131
+ - MANIFEST
132
+ - Rakefile
133
+ - README
134
+ - test
88
135
  - test/test_win32_daemon.rb
89
136
  - test/test_win32_service.rb
90
137
  - test/test_win32_service_configure.rb
@@ -112,7 +159,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
112
159
  version: '0'
113
160
  requirements: []
114
161
  rubyforge_project:
115
- rubygems_version: 2.4.6
162
+ rubygems_version: 2.6.4
116
163
  signing_key:
117
164
  specification_version: 4
118
165
  summary: An interface for MS Windows services
Binary file