[NTOSKRNL] Drop the useless Timestamp field
[reactos.git] / 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 #define COBJMACROS
22
23 #include "config.h"
24 #include <stdarg.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wbemcli.h"
29 #include "winsvc.h"
30
31 #include "wine/debug.h"
32 #include "wbemprox_private.h"
33
34 WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
35
36 static UINT map_error( DWORD error )
37 {
38 switch (error)
39 {
40 case ERROR_SUCCESS: return 0;
41 case ERROR_ACCESS_DENIED: return 2;
42 case ERROR_DEPENDENT_SERVICES_RUNNING: return 3;
43 case ERROR_INVALID_SERVICE_CONTROL: return 4;
44 case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: return 5;
45 case ERROR_SERVICE_NOT_ACTIVE: return 6;
46 case ERROR_SERVICE_REQUEST_TIMEOUT: return 7;
47 case ERROR_SERVICE_ALREADY_RUNNING: return 10;
48 default:
49 WARN("unknown error %u\n", error);
50 break;
51 }
52 return 8;
53 }
54
55 static HRESULT control_service( const WCHAR *name, DWORD control, VARIANT *retval )
56 {
57 SC_HANDLE manager, service = NULL;
58 SERVICE_STATUS status;
59 UINT error = 0;
60
61 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE )))
62 {
63 error = map_error( GetLastError() );
64 goto done;
65 }
66 if (!(service = OpenServiceW( manager, name, SERVICE_STOP|SERVICE_START|SERVICE_PAUSE_CONTINUE )))
67 {
68 error = map_error( GetLastError() );
69 goto done;
70 }
71 if (!ControlService( service, control, &status )) error = map_error( GetLastError() );
72 CloseServiceHandle( service );
73
74 done:
75 set_variant( VT_UI4, error, NULL, retval );
76 if (manager) CloseServiceHandle( manager );
77 return S_OK;
78 }
79
80 HRESULT service_pause_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
81 {
82 VARIANT name, retval;
83 IWbemClassObject *sig, *out_params = NULL;
84 HRESULT hr;
85
86 TRACE("%p, %p, %p\n", obj, in, out);
87
88 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
89 if (hr != S_OK) return hr;
90
91 hr = create_signature( class_serviceW, method_pauseserviceW, PARAM_OUT, &sig );
92 if (hr != S_OK)
93 {
94 VariantClear( &name );
95 return hr;
96 }
97 if (out)
98 {
99 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
100 if (hr != S_OK)
101 {
102 VariantClear( &name );
103 IWbemClassObject_Release( sig );
104 return hr;
105 }
106 }
107 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_PAUSE, &retval );
108 if (hr != S_OK) goto done;
109
110 if (out_params)
111 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
112
113 done:
114 VariantClear( &name );
115 IWbemClassObject_Release( sig );
116 if (hr == S_OK && out)
117 {
118 *out = out_params;
119 IWbemClassObject_AddRef( out_params );
120 }
121 if (out_params) IWbemClassObject_Release( out_params );
122 return hr;
123 }
124
125 HRESULT service_resume_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
126 {
127 VARIANT name, retval;
128 IWbemClassObject *sig, *out_params = NULL;
129 HRESULT hr;
130
131 TRACE("%p, %p, %p\n", obj, in, out);
132
133 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
134 if (hr != S_OK) return hr;
135
136 hr = create_signature( class_serviceW, method_resumeserviceW, PARAM_OUT, &sig );
137 if (hr != S_OK)
138 {
139 VariantClear( &name );
140 return hr;
141 }
142 if (out)
143 {
144 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
145 if (hr != S_OK)
146 {
147 VariantClear( &name );
148 IWbemClassObject_Release( sig );
149 return hr;
150 }
151 }
152 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_CONTINUE, &retval );
153 if (hr != S_OK) goto done;
154
155 if (out_params)
156 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
157
158 done:
159 VariantClear( &name );
160 IWbemClassObject_Release( sig );
161 if (hr == S_OK && out)
162 {
163 *out = out_params;
164 IWbemClassObject_AddRef( out_params );
165 }
166 if (out_params) IWbemClassObject_Release( out_params );
167 return hr;
168 }
169
170 static HRESULT start_service( const WCHAR *name, VARIANT *retval )
171 {
172 SC_HANDLE manager, service = NULL;
173 UINT error = 0;
174
175 if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE )))
176 {
177 error = map_error( GetLastError() );
178 goto done;
179 }
180 if (!(service = OpenServiceW( manager, name, SERVICE_START )))
181 {
182 error = map_error( GetLastError() );
183 goto done;
184 }
185 if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() );
186 CloseServiceHandle( service );
187
188 done:
189 set_variant( VT_UI4, error, NULL, retval );
190 if (manager) CloseServiceHandle( manager );
191 return S_OK;
192 }
193
194 HRESULT service_start_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
195 {
196 VARIANT name, retval;
197 IWbemClassObject *sig, *out_params = NULL;
198 HRESULT hr;
199
200 TRACE("%p, %p, %p\n", obj, in, out);
201
202 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
203 if (hr != S_OK) return hr;
204
205 hr = create_signature( class_serviceW, method_startserviceW, PARAM_OUT, &sig );
206 if (hr != S_OK)
207 {
208 VariantClear( &name );
209 return hr;
210 }
211 if (out)
212 {
213 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
214 if (hr != S_OK)
215 {
216 VariantClear( &name );
217 IWbemClassObject_Release( sig );
218 return hr;
219 }
220 }
221 hr = start_service( V_BSTR(&name), &retval );
222 if (hr != S_OK) goto done;
223
224 if (out_params)
225 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
226
227 done:
228 VariantClear( &name );
229 IWbemClassObject_Release( sig );
230 if (hr == S_OK && out)
231 {
232 *out = out_params;
233 IWbemClassObject_AddRef( out_params );
234 }
235 if (out_params) IWbemClassObject_Release( out_params );
236 return hr;
237 }
238
239 HRESULT service_stop_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
240 {
241 VARIANT name, retval;
242 IWbemClassObject *sig, *out_params = NULL;
243 HRESULT hr;
244
245 TRACE("%p, %p, %p\n", obj, in, out);
246
247 hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL );
248 if (hr != S_OK) return hr;
249
250 hr = create_signature( class_serviceW, method_stopserviceW, PARAM_OUT, &sig );
251 if (hr != S_OK)
252 {
253 VariantClear( &name );
254 return hr;
255 }
256 if (out)
257 {
258 hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
259 if (hr != S_OK)
260 {
261 VariantClear( &name );
262 IWbemClassObject_Release( sig );
263 return hr;
264 }
265 }
266 hr = control_service( V_BSTR(&name), SERVICE_CONTROL_STOP, &retval );
267 if (hr != S_OK) goto done;
268
269 if (out_params)
270 hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
271
272 done:
273 VariantClear( &name );
274 IWbemClassObject_Release( sig );
275 if (hr == S_OK && out)
276 {
277 *out = out_params;
278 IWbemClassObject_AddRef( out_params );
279 }
280 if (out_params) IWbemClassObject_Release( out_params );
281 return hr;
282 }