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