Hans Leidekker : wbemprox: Implement Win32_Service.PauseService.

Alexandre Julliard julliard at winehq.org
Wed Oct 17 14:32:26 CDT 2012


Module: wine
Branch: master
Commit: 8fe25b2b89b4b2e2ae23b079671426ae67fd70d7
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=8fe25b2b89b4b2e2ae23b079671426ae67fd70d7

Author: Hans Leidekker <hans at 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};




More information about the wine-cvs mailing list