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