win32-srv 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,143 @@
1
+ module Windows
2
+ module ServiceConstants
3
+ SC_MANAGER_ALL_ACCESS = 0xF003F
4
+ SC_MANAGER_CREATE_SERVICE = 0x0002
5
+ SC_MANAGER_CONNECT = 0x0001
6
+ SC_MANAGER_ENUMERATE_SERVICE = 0x0004
7
+ SC_MANAGER_LOCK = 0x0008
8
+ SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020
9
+ SC_MANAGER_QUERY_LOCK_STATUS = 0x0010
10
+ SC_STATUS_PROCESS_INFO = 0
11
+ SC_ENUM_PROCESS_INFO = 0
12
+
13
+ # Service control action types
14
+ SC_ACTION_NONE = 0
15
+ SC_ACTION_RESTART = 1
16
+ SC_ACTION_REBOOT = 2
17
+ SC_ACTION_RUN_COMMAND = 3
18
+
19
+ # Service access rights
20
+ SERVICE_ALL_ACCESS = 0xF01FF
21
+ SERVICE_CHANGE_CONFIG = 0x0002
22
+ SERVICE_ENUMERATE_DEPENDENTS = 0x0008
23
+ SERVICE_INTERROGATE = 0x0080
24
+ SERVICE_PAUSE_CONTINUE = 0x0040
25
+ SERVICE_QUERY_CONFIG = 0x0001
26
+ SERVICE_QUERY_STATUS = 0x0004
27
+ SERVICE_START = 0x0010
28
+ SERVICE_STOP = 0x0020
29
+ SERVICE_USER_DEFINED_CONTROL = 0x0100
30
+
31
+ # Service types
32
+ SERVICE_KERNEL_DRIVER = 0x00000001
33
+ SERVICE_FILE_SYSTEM_DRIVER = 0x00000002
34
+ SERVICE_ADAPTER = 0x00000004
35
+ SERVICE_RECOGNIZER_DRIVER = 0x00000008
36
+ SERVICE_WIN32_OWN_PROCESS = 0x00000010
37
+ SERVICE_WIN32_SHARE_PROCESS = 0x00000020
38
+ SERVICE_WIN32 = 0x00000030
39
+ SERVICE_INTERACTIVE_PROCESS = 0x00000100
40
+ SERVICE_DRIVER = 0x0000000B
41
+ SERVICE_TYPE_ALL = 0x0000013F
42
+
43
+ # Error control
44
+ SERVICE_ERROR_IGNORE = 0x00000000
45
+ SERVICE_ERROR_NORMAL = 0x00000001
46
+ SERVICE_ERROR_SEVERE = 0x00000002
47
+ SERVICE_ERROR_CRITICAL = 0x00000003
48
+
49
+ # Start types
50
+ SERVICE_BOOT_START = 0x00000000
51
+ SERVICE_SYSTEM_START = 0x00000001
52
+ SERVICE_AUTO_START = 0x00000002
53
+ SERVICE_DEMAND_START = 0x00000003
54
+ SERVICE_DISABLED = 0x00000004
55
+
56
+ # Service control
57
+
58
+ SERVICE_CONTROL_STOP = 0x00000001
59
+ SERVICE_CONTROL_PAUSE = 0x00000002
60
+ SERVICE_CONTROL_CONTINUE = 0x00000003
61
+ SERVICE_CONTROL_INTERROGATE = 0x00000004
62
+ SERVICE_CONTROL_SHUTDOWN = 0x00000005
63
+ SERVICE_CONTROL_PARAMCHANGE = 0x00000006
64
+ SERVICE_CONTROL_NETBINDADD = 0x00000007
65
+ SERVICE_CONTROL_NETBINDREMOVE = 0x00000008
66
+ SERVICE_CONTROL_NETBINDENABLE = 0x00000009
67
+ SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A
68
+ SERVICE_CONTROL_DEVICEEVENT = 0x0000000B
69
+ SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C
70
+ SERVICE_CONTROL_POWEREVENT = 0x0000000D
71
+ SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E
72
+ SERVICE_CONTROL_PRESHUTDOWN = 0x0000000F
73
+ SERVICE_CONTROL_TIMECHANGE = 0x00000010
74
+ SERVICE_CONTROL_TRIGGEREVENT = 0x00000020
75
+
76
+ # Service controls accepted
77
+
78
+ SERVICE_ACCEPT_STOP = 0x00000001
79
+ SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002
80
+ SERVICE_ACCEPT_SHUTDOWN = 0x00000004
81
+ SERVICE_ACCEPT_PARAMCHANGE = 0x00000008
82
+ SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010
83
+ SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
84
+ SERVICE_ACCEPT_POWEREVENT = 0x00000040
85
+ SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
86
+ SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100
87
+ SERVICE_ACCEPT_TIMECHANGE = 0x00000200
88
+ SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400
89
+
90
+ # Service states
91
+ SERVICE_ACTIVE = 0x00000001
92
+ SERVICE_INACTIVE = 0x00000002
93
+ SERVICE_STATE_ALL = 0x00000003
94
+
95
+ # Service current states
96
+ SERVICE_STOPPED = 0x00000001
97
+ SERVICE_START_PENDING = 0x00000002
98
+ SERVICE_STOP_PENDING = 0x00000003
99
+ SERVICE_RUNNING = 0x00000004
100
+ SERVICE_CONTINUE_PENDING = 0x00000005
101
+ SERVICE_PAUSE_PENDING = 0x00000006
102
+ SERVICE_PAUSED = 0x00000007
103
+
104
+ # Info levels
105
+ SERVICE_CONFIG_DESCRIPTION = 1
106
+ SERVICE_CONFIG_FAILURE_ACTIONS = 2
107
+ SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3
108
+ SERVICE_CONFIG_FAILURE_ACTIONS_FLAG = 4
109
+ SERVICE_CONFIG_SERVICE_SID_INFO = 5
110
+ SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO = 6
111
+ SERVICE_CONFIG_PRESHUTDOWN_INFO = 7
112
+
113
+ # Configuration
114
+ SERVICE_NO_CHANGE = 0xffffffff
115
+
116
+ # Misc
117
+
118
+ WAIT_OBJECT_0 = 0
119
+ WAIT_TIMEOUT = 0x00000102
120
+ INFINITE = 0xFFFFFFFF
121
+
122
+ IDLE_CONTROL_CODE = 0
123
+
124
+ DELETE = 0x00010000
125
+ FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000
126
+ FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200
127
+
128
+ NO_ERROR = 0
129
+
130
+ SE_PRIVILEGE_ENABLED = 0x00000002
131
+ TOKEN_ADJUST_PRIVILEGES = 0x0020
132
+ TOKEN_QUERY = 0x0008
133
+
134
+ # Errors
135
+
136
+ ERROR_INSUFFICIENT_BUFFER = 122
137
+ ERROR_MORE_DATA = 234
138
+ ERROR_FILE_NOT_FOUND = 2
139
+ ERROR_RESOURCE_TYPE_NOT_FOUND = 1813
140
+ ERROR_RESOURCE_NAME_NOT_FOUND = 1814
141
+ WAIT_FAILED = 0xFFFFFFFF
142
+ end
143
+ end
@@ -0,0 +1,75 @@
1
+ require "ffi" unless defined?(FFI)
2
+
3
+ module Windows
4
+ module ServiceFunctions
5
+ extend FFI::Library
6
+
7
+ # Make FFI functions private
8
+ module FFI::Library
9
+ def attach_pfunc(*args)
10
+ attach_function(*args)
11
+ private args[0]
12
+ end
13
+ end
14
+
15
+ typedef :ulong, :dword
16
+ typedef :uintptr_t, :handle
17
+ typedef :pointer, :ptr
18
+ typedef :string, :str
19
+
20
+ ffi_convention :stdcall
21
+
22
+ ffi_lib :kernel32
23
+
24
+ attach_pfunc :CloseHandle, [:handle], :bool
25
+ attach_pfunc :CreateEvent, :CreateEventA, %i{ptr int int str}, :handle
26
+ attach_pfunc :CreateThread, %i{ptr size_t ptr ptr dword ptr}, :handle, blocking: true
27
+ attach_pfunc :EnterCriticalSection, [:ptr], :void
28
+ attach_pfunc :FormatMessage, :FormatMessageA, %i{ulong ptr ulong ulong str ulong ptr}, :ulong
29
+ attach_pfunc :GetCurrentProcess, [], :handle
30
+ attach_pfunc :InitializeCriticalSection, [:ptr], :void
31
+ attach_pfunc :LeaveCriticalSection, [:ptr], :void
32
+ attach_pfunc :SetEvent, [:handle], :bool
33
+ attach_pfunc :WaitForSingleObject, %i{handle dword}, :dword, blocking: true
34
+ attach_pfunc :WaitForMultipleObjects, %i{dword ptr int dword}, :dword
35
+
36
+ ffi_lib :advapi32
37
+
38
+ callback :handler_ex, %i{ulong ulong ptr ptr}, :void
39
+
40
+ attach_pfunc :AdjustTokenPrivileges, %i{handle int ptr dword ptr ptr}, :bool
41
+ attach_pfunc :CloseServiceHandle, [:handle], :bool
42
+
43
+ attach_pfunc :ChangeServiceConfig, :ChangeServiceConfigA,
44
+ %i{handle dword dword dword str str ptr ptr str str str},
45
+ :bool
46
+
47
+ attach_pfunc :ChangeServiceConfig2, :ChangeServiceConfig2A, %i{handle dword ptr}, :bool
48
+
49
+ attach_pfunc :CreateService, :CreateServiceA,
50
+ %i{handle string string dword dword dword dword
51
+ string string ptr pointer string string},
52
+ :handle
53
+
54
+ attach_pfunc :ControlService, %i{handle dword ptr}, :bool
55
+ attach_pfunc :DeleteService, [:handle], :bool
56
+
57
+ attach_pfunc :EnumServicesStatusEx, :EnumServicesStatusExA,
58
+ %i{handle int dword dword ptr dword ptr ptr ptr string},
59
+ :bool
60
+
61
+ attach_pfunc :GetServiceDisplayName, :GetServiceDisplayNameA, %i{handle string ptr ptr}, :bool
62
+ attach_pfunc :GetServiceKeyName, :GetServiceKeyNameA, %i{handle string ptr ptr}, :bool
63
+ attach_pfunc :LookupPrivilegeValue, :LookupPrivilegeValueA, %i{string string ptr}, :bool
64
+ attach_pfunc :OpenSCManager, :OpenSCManagerA, %i{ptr ptr dword}, :handle
65
+ attach_pfunc :OpenProcessToken, %i{handle dword ptr}, :bool
66
+ attach_pfunc :OpenService, :OpenServiceA, %i{handle string dword}, :handle
67
+ attach_pfunc :QueryServiceConfig, :QueryServiceConfigA, %i{handle ptr dword ptr}, :bool
68
+ attach_pfunc :QueryServiceConfig2, :QueryServiceConfig2A, %i{handle dword ptr dword ptr}, :bool
69
+ attach_pfunc :QueryServiceStatusEx, %i{handle int ptr dword ptr}, :bool
70
+ attach_pfunc :RegisterServiceCtrlHandlerEx, :RegisterServiceCtrlHandlerExA, %i{str handler_ex ptr}, :handle
71
+ attach_pfunc :SetServiceStatus, %i{handle ptr}, :bool
72
+ attach_pfunc :StartService, :StartServiceA, %i{handle dword ptr}, :bool
73
+ attach_pfunc :StartServiceCtrlDispatcher, :StartServiceCtrlDispatcherA, [:ptr], :bool, blocking: true
74
+ end
75
+ end
@@ -0,0 +1,121 @@
1
+ require "ffi" unless defined?(FFI)
2
+
3
+ module Windows
4
+ module ServiceStructs
5
+ extend FFI::Library
6
+
7
+ typedef :ulong, :dword
8
+
9
+ class SERVICE_STATUS < FFI::Struct
10
+ layout(
11
+ :dwServiceType, :ulong,
12
+ :dwCurrentState, :ulong,
13
+ :dwControlsAccepted, :ulong,
14
+ :dwWin32ExitCode, :ulong,
15
+ :dwServiceSpecificExitCode, :ulong,
16
+ :dwCheckPoint, :ulong,
17
+ :dwWaitHint, :ulong
18
+ )
19
+ end
20
+
21
+ class SERVICE_STATUS_PROCESS < FFI::Struct
22
+ layout(
23
+ :dwServiceType, :dword,
24
+ :dwCurrentState, :dword,
25
+ :dwControlsAccepted, :dword,
26
+ :dwWin32ExitCode, :dword,
27
+ :dwServiceSpecificExitCode, :dword,
28
+ :dwCheckPoint, :dword,
29
+ :dwWaitHint, :dword,
30
+ :dwProcessId, :dword,
31
+ :dwServiceFlags, :dword
32
+ )
33
+ end
34
+
35
+ class SERVICE_DESCRIPTION < FFI::Struct
36
+ layout(:lpDescription, :pointer)
37
+ end
38
+
39
+ class SERVICE_DELAYED_AUTO_START_INFO < FFI::Struct
40
+ layout(:fDelayedAutostart, :int) # BOOL
41
+
42
+ alias aset []=
43
+
44
+ # Intercept the accessor so that we can handle either true/false or 1/0.
45
+ # Since there is only one member, there's no need to check the key name.
46
+ #
47
+ def []=(key, value)
48
+ [0, false].include?(value) ? aset(key, 0) : aset(key, 1)
49
+ end
50
+ end
51
+
52
+ class QUERY_SERVICE_CONFIG < FFI::Struct
53
+ layout(
54
+ :dwServiceType, :dword,
55
+ :dwStartType, :dword,
56
+ :dwErrorControl, :dword,
57
+ :lpBinaryPathName, :pointer,
58
+ :lpLoadOrderGroup, :pointer,
59
+ :dwTagId, :dword,
60
+ :lpDependencies, :pointer,
61
+ :lpServiceStartName, :pointer,
62
+ :lpDisplayName, :pointer
63
+ )
64
+
65
+ def dependencies
66
+ length = self[:lpServiceStartName].address - self[:lpDependencies].address - 1
67
+ self[:lpDependencies].read_bytes(length).split(0.chr)
68
+ end
69
+ end
70
+
71
+ class ENUM_SERVICE_STATUS_PROCESS < FFI::Struct
72
+ layout(
73
+ :lpServiceName, :pointer,
74
+ :lpDisplayName, :pointer,
75
+ :ServiceStatusProcess, SERVICE_STATUS_PROCESS
76
+ )
77
+ end
78
+
79
+ class SC_ACTION < FFI::Struct
80
+ layout(:Type, :int, :Delay, :dword)
81
+ end
82
+
83
+ class SERVICE_FAILURE_ACTIONS < FFI::Struct
84
+ layout(
85
+ :dwResetPeriod, :dword,
86
+ :lpRebootMsg, :pointer,
87
+ :lpCommand, :pointer,
88
+ :cActions, :dword,
89
+ :lpsaActions, :pointer # Array of SC_ACTION structs
90
+ )
91
+ end
92
+
93
+ class SERVICE_TABLE_ENTRY < FFI::Struct
94
+ layout(
95
+ :lpServiceName, :pointer,
96
+ :lpServiceProc, :pointer
97
+ )
98
+ end
99
+
100
+ class LUID < FFI::Struct
101
+ layout(
102
+ :LowPart, :ulong,
103
+ :HighPart, :long
104
+ )
105
+ end
106
+
107
+ class LUID_AND_ATTRIBUTES < FFI::Struct
108
+ layout(
109
+ :Luid, LUID,
110
+ :Attributes, :ulong
111
+ )
112
+ end
113
+
114
+ class TOKEN_PRIVILEGES < FFI::Struct
115
+ layout(
116
+ :PrivilegeCount, :dword,
117
+ :Privileges, [LUID_AND_ATTRIBUTES, 1]
118
+ )
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,6 @@
1
+ module Win32
2
+ class Service
3
+ VERSION = "1.0.0".freeze
4
+ MAJOR, MINOR, TINY = VERSION.split(".")
5
+ end
6
+ end
@@ -0,0 +1 @@
1
+ require_relative "win32/daemon"
@@ -0,0 +1 @@
1
+ require_relative "win32/service"
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: win32-srv
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Gernot Gradwohl
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ffi
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: ffi-win32-extensions
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec-core
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rspec-expectations
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: rspec-mocks
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ type: :development
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ - !ruby/object:Gem::Dependency
83
+ name: test-unit
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: win32-security
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: |2
111
+ The win32-srv library provides a Ruby interface to services on
112
+ MS Windows. You can create new services, or control, configure and
113
+ inspect existing services.
114
+
115
+ In addition, you can create a pure Ruby service by using the Daemon
116
+ class that is included as part of the library.
117
+ email: grnt.grdwhl@gmail.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - lib/win32-daemon.rb
123
+ - lib/win32-service.rb
124
+ - lib/win32/daemon.rb
125
+ - lib/win32/service.rb
126
+ - lib/win32/windows/constants.rb
127
+ - lib/win32/windows/functions.rb
128
+ - lib/win32/windows/structs.rb
129
+ - lib/win32/windows/version.rb
130
+ homepage: https://github.com/choallin/win32-service
131
+ licenses:
132
+ - MIT
133
+ metadata: {}
134
+ rdoc_options: []
135
+ require_paths:
136
+ - lib
137
+ required_ruby_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '2.3'
142
+ required_rubygems_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ requirements: []
148
+ rubygems_version: 3.6.2
149
+ specification_version: 4
150
+ summary: An interface for MS Windows services
151
+ test_files: []