[WBEMPROX]
[reactos.git] / reactos / dll / win32 / wbemprox / service.c
1 /*
2 * Win32_Service methods implementation
3 *
4 * Copyright 2012 Hans Leidekker for CodeWeavers
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #include "wbemprox_private.h"
22
23 static UINT map_error( DWORD error )
24 {
25 switch (error)
26 {
27 case ERROR_SUCCESS: return 0;
28 case ERROR_ACCESS_DENIED: return 2;
29 case ERROR_DEPENDENT_SERVICES_RUNNING: return 3;
30 case ERROR_INVALID_SERVICE_CONTROL: return 4;
31 case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: return 5;
32 case ERROR_SERVICE_NOT_ACTIVE: return 6;
33 case ERROR_SERVICE_REQUEST_TIMEOUT: return 7;
34 case ERROR_SERVICE_ALREADY_RUNNING: return 10;
35 default:
36 WARN("unknown error %u\n", error);
37 break;
38 }
39 return 8;
40 }
41
42 static HRESULT control_service( const WCHAR *name, DWORD control, VARIANT *retval )
43 {
44 SC_HANDLE manager, service = NULL;
45 SERVICE_STATUS status;
46 UINT error = 0;
47
48 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE )))
49 {
50 error = map_error( GetLastError() );
51 goto done;
52 }
53 if (!(service = OpenServiceW( manager, name, SERVICE_STOP|SERVICE_START|SERVICE_PAUSE_CONTINUE )))
54 {
55 error = map_error( GetLastError() );
56 goto done;
57 }
58 if (!ControlService( service, control, &status )) error = map_error( GetLastError() );
59
60 done:
61 set_variant( VT_UI4, error, NULL, retval );
62 CloseServiceHandle( service );
63 CloseServiceHandle( manager );
64 return S_OK;
65 }
66
67 HRESULT service_pause_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
68 {
69 VARIANT name, retval;
70 IWbemClassObject *sig;
71 HRESULT hr;
72
73 TRACE("%p, %p, %p\n", obj, in, out);
74
75 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
76 if (hr != S_OK) return hr;
77
78 hr = create_signature( class_serviceW, method_pauseserviceW, PARAM_OUT, &sig );
79 if (hr != S_OK)
80 {
81 VariantClear( &name );
82 return hr;
83 }
84 hr = IWbemClassObject_SpawnInstance( sig, 0, out );
85 if (hr != S_OK)
86 {
87 VariantClear( &name );
88 IWbemClassObject_Release( sig );
89 return hr;
90 }
91 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_PAUSE, &retval );
92 if (hr != S_OK) goto done;
93 hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 );
94
95 done:
96 VariantClear( &name );
97 IWbemClassObject_Release( sig );
98 if (hr != S_OK) IWbemClassObject_Release( *out );
99 return hr;
100 }
101
102 HRESULT service_resume_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
103 {
104 VARIANT name, retval;
105 IWbemClassObject *sig;
106 HRESULT hr;
107
108 TRACE("%p, %p, %p\n", obj, in, out);
109
110 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
111 if (hr != S_OK) return hr;
112
113 hr = create_signature( class_serviceW, method_resumeserviceW, PARAM_OUT, &sig );
114 if (hr != S_OK)
115 {
116 VariantClear( &name );
117 return hr;
118 }
119 hr = IWbemClassObject_SpawnInstance( sig, 0, out );
120 if (hr != S_OK)
121 {
122 VariantClear( &name );
123 IWbemClassObject_Release( sig );
124 return hr;
125 }
126 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_CONTINUE, &retval );
127 if (hr != S_OK) goto done;
128 hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 );
129
130 done:
131 VariantClear( &name );
132 IWbemClassObject_Release( sig );
133 if (hr != S_OK) IWbemClassObject_Release( *out );
134 return hr;
135 }
136
137 static HRESULT start_service( const WCHAR *name, VARIANT *retval )
138 {
139 SC_HANDLE manager, service = NULL;
140 UINT error = 0;
141
142 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE )))
143 {
144 error = map_error( GetLastError() );
145 goto done;
146 }
147 if (!(service = OpenServiceW( manager, name, SERVICE_START )))
148 {
149 error = map_error( GetLastError() );
150 goto done;
151 }
152 if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() );
153
154 done:
155 set_variant( VT_UI4, error, NULL, retval );
156 CloseServiceHandle( service );
157 CloseServiceHandle( manager );
158 return S_OK;
159 }
160
161 HRESULT service_start_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
162 {
163 VARIANT name, retval;
164 IWbemClassObject *sig;
165 HRESULT hr;
166
167 TRACE("%p, %p, %p\n", obj, in, out);
168
169 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
170 if (hr != S_OK) return hr;
171
172 hr = create_signature( class_serviceW, method_startserviceW, PARAM_OUT, &sig );
173 if (hr != S_OK)
174 {
175 VariantClear( &name );
176 return hr;
177 }
178 hr = IWbemClassObject_SpawnInstance( sig, 0, out );
179 if (hr != S_OK)
180 {
181 VariantClear( &name );
182 IWbemClassObject_Release( sig );
183 return hr;
184 }
185 hr = start_service( V_BSTR(&name), &retval );
186 if (hr != S_OK) goto done;
187 hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 );
188
189 done:
190 VariantClear( &name );
191 IWbemClassObject_Release( sig );
192 if (hr != S_OK) IWbemClassObject_Release( *out );
193 return hr;
194 }
195
196 HRESULT service_stop_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
197 {
198 VARIANT name, retval;
199 IWbemClassObject *sig;
200 HRESULT hr;
201
202 TRACE("%p, %p, %p\n", obj, in, out);
203
204 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
205 if (hr != S_OK) return hr;
206
207 hr = create_signature( class_serviceW, method_stopserviceW, PARAM_OUT, &sig );
208 if (hr != S_OK)
209 {
210 VariantClear( &name );
211 return hr;
212 }
213 hr = IWbemClassObject_SpawnInstance( sig, 0, out );
214 if (hr != S_OK)
215 {
216 VariantClear( &name );
217 IWbemClassObject_Release( sig );
218 return hr;
219 }
220 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_STOP, &retval );
221 if (hr != S_OK) goto done;
222 hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 );
223
224 done:
225 VariantClear( &name );
226 IWbemClassObject_Release( sig );
227 if (hr != S_OK) IWbemClassObject_Release( *out );
228 return hr;
229 }