win32-service 0.8.7 → 0.8.8

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 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