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