diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 5ed27422065..69fbc18c86c 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -294,7 +294,8 @@ static const struct column col_service[] = { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC }, /* methods */ { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, - { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } + { method_resumeserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }, + { method_startserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } }; static const struct column col_sounddevice[] = { @@ -475,6 +476,7 @@ struct record_service /* methods */ class_method *pause_service; class_method *resume_service; + class_method *start_service; }; struct record_sounddevice { @@ -518,6 +520,7 @@ static const struct record_params data_params[] = { { class_serviceW, method_pauseserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, + { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 }, { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING }, { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 }, @@ -1118,6 +1121,7 @@ static void fill_service( struct table *table ) rec->systemname = heap_strdupW( sysnameW ); rec->pause_service = service_pause_service; rec->resume_service = service_resume_service; + rec->start_service = service_start_service; heap_free( config ); offset += sizeof(*rec); num_rows++; diff --git a/dlls/wbemprox/service.c b/dlls/wbemprox/service.c index f381a4b0699..cd377b9f79b 100644 --- a/dlls/wbemprox/service.c +++ b/dlls/wbemprox/service.c @@ -146,3 +146,62 @@ done: if (hr != S_OK) IWbemClassObject_Release( *out ); return hr; } + +static HRESULT start_service( const WCHAR *name, VARIANT *retval ) +{ + SC_HANDLE manager, service = NULL; + UINT error = 0; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!(service = OpenServiceW( manager, name, SERVICE_START ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!StartServiceW( service, 0, NULL )) error = map_error( GetLastError() ); + +done: + set_variant( VT_UI4, error, NULL, retval ); + CloseServiceHandle( service ); + CloseServiceHandle( manager ); + return S_OK; +} + +HRESULT service_start_service( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out ) +{ + VARIANT name, retval; + IWbemClassObject *sig; + HRESULT hr; + + TRACE("%p, %p, %p\n", obj, in, out); + + hr = IWbemClassObject_Get( obj, prop_nameW, 0, &name, NULL, NULL ); + if (hr != S_OK) return hr; + + hr = create_signature( class_serviceW, method_startserviceW, PARAM_OUT, &sig ); + if (hr != S_OK) + { + VariantClear( &name ); + return hr; + } + hr = IWbemClassObject_SpawnInstance( sig, 0, out ); + if (hr != S_OK) + { + VariantClear( &name ); + IWbemClassObject_Release( sig ); + return hr; + } + hr = start_service( V_BSTR(&name), &retval ); + if (hr != S_OK) goto done; + hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 ); + +done: + VariantClear( &name ); + IWbemClassObject_Release( sig ); + if (hr != S_OK) IWbemClassObject_Release( *out ); + return hr; +} diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h index 7f5bc6ae2bc..39870bf5b4b 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -203,6 +203,7 @@ HRESULT reg_enum_values(IWbemClassObject *, IWbemClassObject *, IWbemClassObject HRESULT reg_get_stringvalue(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT service_pause_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT service_resume_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_start_service(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); static inline void *heap_alloc( size_t len ) @@ -245,6 +246,7 @@ static const WCHAR method_enumvaluesW[] = {'E','n','u','m','V','a','l','u','e',' static const WCHAR method_getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0}; static const WCHAR method_pauseserviceW[] = {'P','a','u','s','e','S','e','r','v','i','c','e',0}; static const WCHAR method_resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0}; +static const WCHAR method_startserviceW[] = {'S','t','a','r','t','S','e','r','v','i','c','e',0}; static const WCHAR param_defkeyW[] = {'h','D','e','f','K','e','y',0}; static const WCHAR param_namesW[] = {'s','N','a','m','e','s',0};