Module: wine Branch: master Commit: 8fe25b2b89b4b2e2ae23b079671426ae67fd70d7 URL: http://source.winehq.org/git/wine.git/?a=commit;h=8fe25b2b89b4b2e2ae23b07967...
Author: Hans Leidekker hans@codeweavers.com Date: Wed Oct 17 11:07:17 2012 +0200
wbemprox: Implement Win32_Service.PauseService.
---
dlls/wbemprox/Makefile.in | 1 + dlls/wbemprox/builtin.c | 30 +++++----- dlls/wbemprox/service.c | 113 ++++++++++++++++++++++++++++++++++++++ dlls/wbemprox/wbemprox_private.h | 5 ++ 4 files changed, 135 insertions(+), 14 deletions(-)
diff --git a/dlls/wbemprox/Makefile.in b/dlls/wbemprox/Makefile.in index b04bb64..bd96a99 100644 --- a/dlls/wbemprox/Makefile.in +++ b/dlls/wbemprox/Makefile.in @@ -7,6 +7,7 @@ C_SRCS = \ main.c \ query.c \ reg.c \ + service.c \ services.c \ table.c \ wbemlocator.c diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 9e515ef..5138fde 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -65,8 +65,6 @@ static const WCHAR class_processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0}; static const WCHAR class_processorW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','o','r',0}; -static const WCHAR class_serviceW[] = - {'W','i','n','3','2','_','S','e','r','v','i','c','e',0}; static const WCHAR class_sounddeviceW[] = {'W','i','n','3','2','_','S','o','u','n','d','D','e','v','i','c','e',0}; static const WCHAR class_videocontrollerW[] = @@ -132,8 +130,6 @@ static const WCHAR prop_methodW[] = {'M','e','t','h','o','d',0}; static const WCHAR prop_modelW[] = {'M','o','d','e','l',0}; -static const WCHAR prop_nameW[] = - {'N','a','m','e',0}; static const WCHAR prop_netconnectionstatusW[] = {'N','e','t','C','o','n','n','e','c','t','i','o','n','S','t','a','t','u','s',0}; static const WCHAR prop_numlogicalprocessorsW[] = @@ -295,7 +291,9 @@ static const struct column col_service[] = { prop_servicetypeW, CIM_STRING }, { prop_startmodeW, CIM_STRING }, { prop_stateW, CIM_STRING }, - { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC } + { prop_systemnameW, CIM_STRING|COL_FLAG_DYNAMIC }, + /* methods */ + { method_pauseserviceW, CIM_FLAG_ARRAY|COL_FLAG_METHOD } }; static const struct column col_sounddevice[] = { @@ -473,6 +471,8 @@ struct record_service const WCHAR *startmode; const WCHAR *state; const WCHAR *systemname; + /* methods */ + class_method *pause_service; }; struct record_sounddevice { @@ -514,6 +514,7 @@ static const struct record_diskdrive data_diskdrive[] = }; static const struct record_params data_params[] = { + { class_serviceW, method_pauseserviceW, -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 }, @@ -1103,15 +1104,16 @@ static void fill_service( struct table *table )
status = &services[i].ServiceStatusProcess; rec = (struct record_service *)(table->data + offset); - rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0; - rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0; - rec->displayname = heap_strdupW( services[i].lpDisplayName ); - rec->name = heap_strdupW( services[i].lpServiceName ); - rec->process_id = status->dwProcessId; - rec->servicetype = get_service_type( status->dwServiceType ); - rec->startmode = get_service_startmode( config->dwStartType ); - rec->state = get_service_state( status->dwCurrentState ); - rec->systemname = heap_strdupW( sysnameW ); + rec->accept_pause = (status->dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) ? -1 : 0; + rec->accept_stop = (status->dwControlsAccepted & SERVICE_ACCEPT_STOP) ? -1 : 0; + rec->displayname = heap_strdupW( services[i].lpDisplayName ); + rec->name = heap_strdupW( services[i].lpServiceName ); + rec->process_id = status->dwProcessId; + rec->servicetype = get_service_type( status->dwServiceType ); + rec->startmode = get_service_startmode( config->dwStartType ); + rec->state = get_service_state( status->dwCurrentState ); + rec->systemname = heap_strdupW( sysnameW ); + rec->pause_service = service_pause_service; heap_free( config ); offset += sizeof(*rec); num_rows++; diff --git a/dlls/wbemprox/service.c b/dlls/wbemprox/service.c new file mode 100644 index 0000000..7c6aabf --- /dev/null +++ b/dlls/wbemprox/service.c @@ -0,0 +1,113 @@ +/* + * Win32_Service methods implementation + * + * Copyright 2012 Hans Leidekker for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "config.h" +#include <stdarg.h> + +#include "windef.h" +#include "winbase.h" +#include "wbemcli.h" +#include "winsvc.h" + +#include "wine/debug.h" +#include "wbemprox_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wbemprox); + +static UINT map_error( DWORD error ) +{ + switch (error) + { + case ERROR_SUCCESS: return 0; + case ERROR_ACCESS_DENIED: return 2; + case ERROR_DEPENDENT_SERVICES_RUNNING: return 3; + case ERROR_INVALID_SERVICE_CONTROL: return 4; + case ERROR_SERVICE_CANNOT_ACCEPT_CTRL: return 5; + case ERROR_SERVICE_NOT_ACTIVE: return 6; + case ERROR_SERVICE_REQUEST_TIMEOUT: return 7; + case ERROR_SERVICE_ALREADY_RUNNING: return 10; + default: + WARN("unknown error %u\n", error); + break; + } + return 8; +} + +static HRESULT control_service( const WCHAR *name, DWORD control, VARIANT *retval ) +{ + SC_HANDLE manager, service = NULL; + SERVICE_STATUS status; + UINT error = 0; + + if (!(manager = OpenSCManagerW( NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!(service = OpenServiceW( manager, name, SERVICE_STOP|SERVICE_START|SERVICE_PAUSE_CONTINUE ))) + { + error = map_error( GetLastError() ); + goto done; + } + if (!ControlService( service, control, &status )) error = map_error( GetLastError() ); + +done: + set_variant( VT_UI4, error, NULL, retval ); + CloseServiceHandle( service ); + CloseServiceHandle( manager ); + return S_OK; +} + +HRESULT service_pause_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_pauseserviceW, 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 = control_service( V_BSTR(&name), SERVICE_CONTROL_PAUSE, &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 05da3c6..c2181c0 100644 --- a/dlls/wbemprox/wbemprox_private.h +++ b/dlls/wbemprox/wbemprox_private.h @@ -201,6 +201,7 @@ HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) DECLSPE HRESULT reg_enum_key(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT reg_enum_values(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; HRESULT reg_get_stringvalue(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN; +HRESULT service_pause_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 ) @@ -233,11 +234,15 @@ static inline WCHAR *heap_strdupW( const WCHAR *src ) return dst; }
+static const WCHAR class_serviceW[] = {'W','i','n','3','2','_','S','e','r','v','i','c','e',0}; static const WCHAR class_stdregprovW[] = {'S','t','d','R','e','g','P','r','o','v',0};
+static const WCHAR prop_nameW[] = {'N','a','m','e',0}; + static const WCHAR method_enumkeyW[] = {'E','n','u','m','K','e','y',0}; static const WCHAR method_enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0}; 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 param_defkeyW[] = {'h','D','e','f','K','e','y',0}; static const WCHAR param_namesW[] = {'s','N','a','m','e','s',0};