diff --git a/dlls/wbemprox/Makefile.in b/dlls/wbemprox/Makefile.in index bd96a99471d..31d83cf619e 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 3608a0ce697..4375d759b1d 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 00000000000..918ba9173ec --- /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 + +#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 fdff192b2ce..a23a45d8b83 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 07e8632651d..71c613a15e1 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 435173213e0..54cb84e05db 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};