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