a399a85119de434bf66c51aa2be689b6679a79f3
[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, *out_params = NULL;
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 if (out)
85 {
86 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
87 if (hr != S_OK)
88 {
89 VariantClear( &name );
90 IWbemClassObject_Release( sig );
91 return hr;
92 }
93 }
94 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_PAUSE, &retval );
95 if (hr != S_OK) goto done;
96
97 if (out_params)
98 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
99
100 done:
101 VariantClear( &name );
102 IWbemClassObject_Release( sig );
103 if (hr == S_OK && out)
104 {
105 *out = out_params;
106 IWbemClassObject_AddRef( out_params );
107 }
108 if (out_params) IWbemClassObject_Release( out_params );
109 return hr;
110 }
111
112 HRESULT service_resume_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
113 {
114 VARIANT name, retval;
115 IWbemClassObject *sig, *out_params = NULL;
116 HRESULT hr;
117
118 TRACE("%p, %p, %p\n", obj, in, out);
119
120 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
121 if (hr != S_OK) return hr;
122
123 hr = create_signature( class_serviceW, method_resumeserviceW, PARAM_OUT, &sig );
124 if (hr != S_OK)
125 {
126 VariantClear( &name );
127 return hr;
128 }
129 if (out)
130 {
131 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
132 if (hr != S_OK)
133 {
134 VariantClear( &name );
135 IWbemClassObject_Release( sig );
136 return hr;
137 }
138 }
139 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_CONTINUE, &retval );
140 if (hr != S_OK) goto done;
141
142 if (out_params)
143 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
144
145 done:
146 VariantClear( &name );
147 IWbemClassObject_Release( sig );
148 if (hr == S_OK && out)
149 {
150 *out = out_params;
151 IWbemClassObject_AddRef( out_params );
152 }
153 if (out_params) IWbemClassObject_Release( out_params );
154 return hr;
155 }
156
157 static HRESULT start_service( const WCHAR *name, VARIANT *retval )
158 {
159 SC_HANDLE manager, service = NULL;
160 UINT error = 0;
161
162 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE )))
163 {
164 error = map_error( GetLastError() );
165 goto done;
166 }
167 if (!(service = OpenServiceW( manager, name, SERVICE_START )))
168 {
169 error = map_error( GetLastError() );
170 goto done;
171 }
172 if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() );
173
174 done:
175 set_variant( VT_UI4, error, NULL, retval );
176 CloseServiceHandle( service );
177 CloseServiceHandle( manager );
178 return S_OK;
179 }
180
181 HRESULT service_start_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
182 {
183 VARIANT name, retval;
184 IWbemClassObject *sig, *out_params = NULL;
185 HRESULT hr;
186
187 TRACE("%p, %p, %p\n", obj, in, out);
188
189 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
190 if (hr != S_OK) return hr;
191
192 hr = create_signature( class_serviceW, method_startserviceW, PARAM_OUT, &sig );
193 if (hr != S_OK)
194 {
195 VariantClear( &name );
196 return hr;
197 }
198 if (out)
199 {
200 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
201 if (hr != S_OK)
202 {
203 VariantClear( &name );
204 IWbemClassObject_Release( sig );
205 return hr;
206 }
207 }
208 hr = start_service( V_BSTR(&name), &retval );
209 if (hr != S_OK) goto done;
210
211 if (out_params)
212 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
213
214 done:
215 VariantClear( &name );
216 IWbemClassObject_Release( sig );
217 if (hr == S_OK && out)
218 {
219 *out = out_params;
220 IWbemClassObject_AddRef( out_params );
221 }
222 if (out_params) IWbemClassObject_Release( out_params );
223 return hr;
224 }
225
226 HRESULT service_stop_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
227 {
228 VARIANT name, retval;
229 IWbemClassObject *sig, *out_params = NULL;
230 HRESULT hr;
231
232 TRACE("%p, %p, %p\n", obj, in, out);
233
234 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
235 if (hr != S_OK) return hr;
236
237 hr = create_signature( class_serviceW, method_stopserviceW, PARAM_OUT, &sig );
238 if (hr != S_OK)
239 {
240 VariantClear( &name );
241 return hr;
242 }
243 if (out)
244 {
245 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
246 if (hr != S_OK)
247 {
248 VariantClear( &name );
249 IWbemClassObject_Release( sig );
250 return hr;
251 }
252 }
253 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_STOP, &retval );
254 if (hr != S_OK) goto done;
255
256 if (out_params)
257 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
258
259 done:
260 VariantClear( &name );
261 IWbemClassObject_Release( sig );
262 if (hr == S_OK && out)
263 {
264 *out = out_params;
265 IWbemClassObject_AddRef( out_params );
266 }
267 if (out_params) IWbemClassObject_Release( out_params );
268 return hr;
269 }