[2/2] wbemprox: Implement Win32_Process::GetOwner.

Hans Leidekker hans at codeweavers.com
Fri Jan 11 10:22:14 CST 2013


Should fix http://bugs.winehq.org/show_bug.cgi?id=32685
---
 dlls/wbemprox/Makefile.in        |    1 +
 dlls/wbemprox/builtin.c          |   12 +++--
 dlls/wbemprox/process.c          |  102 ++++++++++++++++++++++++++++++++++++++
 dlls/wbemprox/tests/Makefile.in  |    2 +-
 dlls/wbemprox/tests/query.c      |   65 ++++++++++++++++++++++++
 dlls/wbemprox/wbemprox_private.h |    5 ++
 6 files changed, 183 insertions(+), 4 deletions(-)
 create mode 100644 dlls/wbemprox/process.c

diff --git a/dlls/wbemprox/Makefile.in b/dlls/wbemprox/Makefile.in
index bd96a99..31d83cf 100644
--- a/dlls/wbemprox/Makefile.in
+++ b/dlls/wbemprox/Makefile.in
@@ -5,6 +5,7 @@ C_SRCS = \
 	builtin.c \
 	class.c \
 	main.c \
+	process.c \
 	query.c \
 	reg.c \
 	service.c \
diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 3608a0c..4375d75 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -61,8 +61,6 @@ static const WCHAR class_osW[] =
     {'W','i','n','3','2','_','O','p','e','r','a','t','i','n','g','S','y','s','t','e','m',0};
 static const WCHAR class_paramsW[] =
     {'_','_','P','A','R','A','M','E','T','E','R','S',0};
-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_sounddeviceW[] =
@@ -268,7 +266,9 @@ static const struct column col_process[] =
     { prop_handleW,      CIM_STRING|COL_FLAG_DYNAMIC|COL_FLAG_KEY },
     { prop_pprocessidW,  CIM_UINT32, VT_I4 },
     { prop_processidW,   CIM_UINT32, VT_I4 },
-    { prop_threadcountW, CIM_UINT32, VT_I4 }
+    { prop_threadcountW, CIM_UINT32, VT_I4 },
+    /* methods */
+    { method_getownerW,  CIM_FLAG_ARRAY|COL_FLAG_METHOD }
 };
 static const struct column col_processor[] =
 {
@@ -451,6 +451,8 @@ struct record_process
     UINT32       pprocess_id;
     UINT32       process_id;
     UINT32       thread_count;
+    /* methods */
+    class_method *get_owner;
 };
 struct record_processor
 {
@@ -520,6 +522,9 @@ static const struct record_diskdrive data_diskdrive[] =
 };
 static const struct record_params data_params[] =
 {
+    { class_processW, method_getownerW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_processW, method_getownerW, -1, param_userW, CIM_STRING },
+    { class_processW, method_getownerW, -1, param_domainW, CIM_STRING },
     { 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 },
@@ -812,6 +817,7 @@ static void fill_process( struct table *table )
         rec->process_id   = entry.th32ProcessID;
         rec->pprocess_id  = entry.th32ParentProcessID;
         rec->thread_count = entry.cntThreads;
+        rec->get_owner    = process_get_owner;
         offset += sizeof(*rec);
         num_rows++;
     } while (Process32NextW( snap, &entry ));
diff --git a/dlls/wbemprox/process.c b/dlls/wbemprox/process.c
new file mode 100644
index 0000000..d6b0559
--- /dev/null
+++ b/dlls/wbemprox/process.c
@@ -0,0 +1,102 @@
+/*
+ * Win32_Process methods implementation
+ *
+ * Copyright 2013 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 "wine/debug.h"
+#include "wbemprox_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(wbemprox);
+
+static HRESULT get_owner( VARIANT *user, VARIANT *domain, VARIANT *retval )
+{
+    DWORD len;
+    UINT error = 8;
+
+    len = 0;
+    GetUserNameW( NULL, &len );
+    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto done;
+    if (!(V_BSTR( user ) = heap_alloc( len * sizeof(WCHAR) ))) goto done;
+    if (!GetUserNameW( V_BSTR( user ), &len )) goto done;
+    V_VT( user ) = VT_BSTR;
+
+    len = 0;
+    GetComputerNameW( NULL, &len );
+    if (GetLastError() != ERROR_BUFFER_OVERFLOW) goto done;
+    if (!(V_BSTR( domain ) = heap_alloc( len * sizeof(WCHAR) ))) goto done;
+    if (!GetComputerNameW( V_BSTR( domain ), &len )) goto done;
+    V_VT( domain ) = VT_BSTR;
+
+    error = 0;
+
+done:
+    if (error)
+    {
+        VariantClear( user );
+        VariantClear( domain );
+    }
+    set_variant( VT_UI4, error, NULL, retval );
+    return S_OK;
+}
+
+HRESULT process_get_owner( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
+{
+    VARIANT user, domain, retval;
+    IWbemClassObject *sig;
+    HRESULT hr;
+    
+    TRACE("%p, %p, %p\n", obj, in, out);
+    
+    hr = create_signature( class_processW, method_getownerW, PARAM_OUT, &sig );
+    if (hr != S_OK) return hr;
+
+    hr = IWbemClassObject_SpawnInstance( sig, 0, out );
+    if (hr != S_OK)
+    {   
+        IWbemClassObject_Release( sig );
+        return hr;
+    }
+    VariantInit( &user );
+    VariantInit( &domain );
+    hr = get_owner( &user, &domain, &retval );
+    if (hr != S_OK) goto done;
+    if (!V_UI4( &retval ))
+    {
+        hr = IWbemClassObject_Put( *out, param_userW, 0, &user, CIM_STRING );
+        if (hr != S_OK) goto done;
+        hr = IWbemClassObject_Put( *out, param_domainW, 0, &domain, CIM_STRING );
+        if (hr != S_OK) goto done;
+    }
+    hr = IWbemClassObject_Put( *out, param_returnvalueW, 0, &retval, CIM_UINT32 );
+
+done:
+    VariantClear( &user );
+    VariantClear( &domain );
+    IWbemClassObject_Release( sig );
+    if (hr != S_OK) IWbemClassObject_Release( *out );
+    return hr;
+}
diff --git a/dlls/wbemprox/tests/Makefile.in b/dlls/wbemprox/tests/Makefile.in
index fdff192..a23a45d 100644
--- a/dlls/wbemprox/tests/Makefile.in
+++ b/dlls/wbemprox/tests/Makefile.in
@@ -1,5 +1,5 @@
 TESTDLL   = wbemprox.dll
-IMPORTS   = uuid oleaut32 ole32
+IMPORTS   = uuid oleaut32 ole32 user32
 
 C_SRCS = \
 	query.c \
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c
index 07e8632..71c613a 100644
--- a/dlls/wbemprox/tests/query.c
+++ b/dlls/wbemprox/tests/query.c
@@ -212,6 +212,70 @@ static void test_Win32_Service( IWbemServices *services )
     SysFreeString( class );
 }
 
+static void test_Win32_Process( IWbemServices *services )
+{
+    static const WCHAR returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
+    static const WCHAR getownerW[] = {'G','e','t','O','w','n','e','r',0};
+    static const WCHAR userW[] = {'U','s','e','r',0};
+    static const WCHAR domainW[] = {'D','o','m','a','i','n',0};
+    static const WCHAR processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0};
+    static const WCHAR fmtW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s','.',
+        'H','a','n','d','l','e','=','"','%','u','"',0};
+    BSTR class, method;
+    IWbemClassObject *process, *out;
+    VARIANT user, domain, retval;
+    CIMTYPE type;
+    HRESULT hr;
+
+    class = SysAllocString( processW );
+    hr = IWbemServices_GetObject( services, class, 0, NULL, &process, NULL );
+    SysFreeString( class );
+    if (hr != S_OK)
+    {
+        win_skip( "Win32_Process not available\n" );
+        return;
+    }
+    hr = IWbemClassObject_GetMethod( process, getownerW, 0, NULL, NULL );
+    ok( hr == S_OK, "failed to get GetOwner method %08x\n", hr );
+
+    out = NULL;
+    method = SysAllocString( getownerW );
+    class = SysAllocStringLen( NULL, sizeof(fmtW)/sizeof(fmtW[0]) + 10 );
+    wsprintfW( class, fmtW, GetCurrentProcessId() );
+    hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, NULL, &out, NULL );
+    ok( hr == S_OK, "failed to execute method %08x\n", hr );
+    SysFreeString( method );
+    SysFreeString( class );
+
+    type = 0xdeadbeef;
+    VariantInit( &retval );
+    hr = IWbemClassObject_Get( out, returnvalueW, 0, &retval, &type, NULL );
+    ok( hr == S_OK, "failed to get return value %08x\n", hr );
+    ok( V_VT( &retval ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &retval ) );
+    ok( !V_I4( &retval ), "unexpected error %u\n", V_I4( &retval ) );
+    ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+
+    type = 0xdeadbeef;
+    VariantInit( &user );
+    hr = IWbemClassObject_Get( out, userW, 0, &user, &type, NULL );
+    ok( hr == S_OK, "failed to get user %08x\n", hr );
+    ok( V_VT( &user ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &user ) );
+    ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
+    trace("%s\n", wine_dbgstr_w(V_BSTR(&user)));
+
+    type = 0xdeadbeef;
+    VariantInit( &domain );
+    hr = IWbemClassObject_Get( out, domainW, 0, &domain, &type, NULL );
+    ok( hr == S_OK, "failed to get domain %08x\n", hr );
+    ok( V_VT( &domain ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &domain ) );
+    ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
+    trace("%s\n", wine_dbgstr_w(V_BSTR(&domain)));
+
+    VariantClear( &user );
+    VariantClear( &domain );
+    IWbemClassObject_Release( out );
+}
+
 static void test_StdRegProv( IWbemServices *services )
 {
     static const WCHAR enumkeyW[] = {'E','n','u','m','K','e','y',0};
@@ -414,6 +478,7 @@ START_TEST(query)
     ok( hr == S_OK, "failed to set proxy blanket %08x\n", hr );
 
     test_select( services );
+    test_Win32_Process( services );
     test_Win32_Service( services );
     test_StdRegProv( services );
 
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index 4351732..54cb84e 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -198,6 +198,7 @@ HRESULT create_class_object(const WCHAR *, IEnumWbemClassObject *, UINT,
                             struct record *, IWbemClassObject **) DECLSPEC_HIDDEN;
 HRESULT EnumWbemClassObject_create(IUnknown *, struct query *, LPVOID *) DECLSPEC_HIDDEN;
 
+HRESULT process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN;
 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;
@@ -237,6 +238,7 @@ static inline WCHAR *heap_strdupW( const WCHAR *src )
     return dst;
 }
 
+static const WCHAR class_processW[] = {'W','i','n','3','2','_','P','r','o','c','e','s','s',0};
 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};
 
@@ -244,6 +246,7 @@ 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_getownerW[] = {'G','e','t','O','w','n','e','r',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 method_resumeserviceW[] = {'R','e','s','u','m','e','S','e','r','v','i','c','e',0};
@@ -251,9 +254,11 @@ static const WCHAR method_startserviceW[] = {'S','t','a','r','t','S','e','r','v'
 static const WCHAR method_stopserviceW[] = {'S','t','o','p','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_domainW[] = {'D','o','m','a','i','n',0};
 static const WCHAR param_namesW[] = {'s','N','a','m','e','s',0};
 static const WCHAR param_returnvalueW[] = {'R','e','t','u','r','n','V','a','l','u','e',0};
 static const WCHAR param_subkeynameW[] = {'s','S','u','b','K','e','y','N','a','m','e',0};
 static const WCHAR param_typesW[] = {'T','y','p','e','s',0};
+static const WCHAR param_userW[] = {'U','s','e','r',0};
 static const WCHAR param_valueW[] = {'s','V','a','l','u','e',0};
 static const WCHAR param_valuenameW[] = {'s','V','a','l','u','e','N','a','m','e',0};
-- 
1.7.10.4






More information about the wine-patches mailing list