xref: /reactos/dll/win32/wbemprox/service.c (revision 0623a6f8)
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 }
283