Tests based on a patch by Alistair Leslie-Hughes.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=44474 Signed-off-by: Hans Leidekker hans@codeweavers.com --- dlls/wbemdisp/locator.c | 102 +++++++++++++++++++++++++++++++---------- dlls/wbemdisp/tests/wbemdisp.c | 35 ++++++++++++++ 2 files changed, 112 insertions(+), 25 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index 1c7f56ad25..78b81d8551 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -488,11 +488,13 @@ static HRESULT SWbemPropertySet_create( IWbemClassObject *wbem_object, ISWbemPro return S_OK; }
-#define DISPID_BASE 0x1800000 +#define DISPID_BASE 0x1800000 +#define DISPID_BASE_METHOD 0x1000000
struct member { BSTR name; + BOOL is_method; DISPID dispid; };
@@ -504,6 +506,7 @@ struct object struct member *members; UINT nb_members; DISPID last_dispid; + DISPID last_dispid_method; };
static inline struct object *impl_from_ISWbemObject( @@ -585,41 +588,83 @@ static HRESULT WINAPI object_GetTypeInfo(
static HRESULT init_members( struct object *object ) { - LONG bound, i; - SAFEARRAY *sa; + IWbemClassObject *sig_in, *sig_out; + LONG i = 0, count = 0; + BSTR name; HRESULT hr;
if (object->members) return S_OK;
- hr = IWbemClassObject_GetNames( object->object, NULL, 0, NULL, &sa ); - if (FAILED( hr )) return hr; - hr = SafeArrayGetUBound( sa, 1, &bound ); - if (FAILED( hr )) + hr = IWbemClassObject_BeginEnumeration( object->object, 0 ); + if (SUCCEEDED( hr )) { - SafeArrayDestroy( sa ); - return hr; + while (IWbemClassObject_Next( object->object, 0, NULL, NULL, NULL, NULL ) == S_OK) count++; + IWbemClassObject_EndEnumeration( object->object ); } - if (!(object->members = heap_alloc( sizeof(struct member) * (bound + 1) ))) + + hr = IWbemClassObject_BeginMethodEnumeration( object->object, 0 ); + if (SUCCEEDED( hr )) { - SafeArrayDestroy( sa ); - return E_OUTOFMEMORY; + while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK) + { + count++; + SysFreeString( name ); + IWbemClassObject_Release( sig_in ); + IWbemClassObject_Release( sig_out ); + } + IWbemClassObject_EndMethodEnumeration( object->object ); } - for (i = 0; i <= bound; i++) + + if (!(object->members = heap_alloc( sizeof(struct member) * count ))) return E_OUTOFMEMORY; + + hr = IWbemClassObject_BeginEnumeration( object->object, 0 ); + if (SUCCEEDED( hr )) { - hr = SafeArrayGetElement( sa, &i, &object->members[i].name ); - if (FAILED( hr )) + while (IWbemClassObject_Next( object->object, 0, &name, NULL, NULL, NULL ) == S_OK) { - for (i--; i >= 0; i--) SysFreeString( object->members[i].name ); - SafeArrayDestroy( sa ); - heap_free( object->members ); - object->members = NULL; - return E_OUTOFMEMORY; + object->members[i].name = name; + object->members[i].is_method = FALSE; + object->members[i].dispid = 0; + if (++i > count) + { + IWbemClassObject_EndEnumeration( object->object ); + goto error; + } + TRACE( "added property %s\n", debugstr_w(name) ); } - object->members[i].dispid = 0; + IWbemClassObject_EndEnumeration( object->object ); } - object->nb_members = bound + 1; - SafeArrayDestroy( sa ); + + hr = IWbemClassObject_BeginMethodEnumeration( object->object, 0 ); + if (SUCCEEDED( hr )) + { + while (IWbemClassObject_NextMethod( object->object, 0, &name, &sig_in, &sig_out ) == S_OK) + { + object->members[i].name = name; + object->members[i].is_method = TRUE; + object->members[i].dispid = 0; + if (++i > count) + { + IWbemClassObject_EndMethodEnumeration( object->object ); + goto error; + } + IWbemClassObject_Release( sig_in ); + IWbemClassObject_Release( sig_out ); + TRACE( "added method %s\n", debugstr_w(name) ); + } + IWbemClassObject_EndMethodEnumeration( object->object ); + } + + object->nb_members = count; + TRACE( "added %u members\n", object->nb_members ); return S_OK; + +error: + for (--i; i >= 0; i--) SysFreeString( object->members[i].name ); + heap_free( object->members ); + object->members = NULL; + object->nb_members = 0; + return E_FAIL; }
static DISPID get_member_dispid( struct object *object, const WCHAR *name ) @@ -629,7 +674,13 @@ static DISPID get_member_dispid( struct object *object, const WCHAR *name ) { if (!strcmpiW( object->members[i].name, name )) { - if (!object->members[i].dispid) object->members[i].dispid = ++object->last_dispid; + if (!object->members[i].dispid) + { + if (object->members[i].is_method) + object->members[i].dispid = ++object->last_dispid_method; + else + object->members[i].dispid = ++object->last_dispid; + } return object->members[i].dispid; } } @@ -701,7 +752,7 @@ static HRESULT WINAPI object_Invoke( TRACE( "%p, %x, %s, %u, %x, %p, %p, %p, %p\n", object, member, debugstr_guid(riid), lcid, flags, params, result, excep_info, arg_err );
- if (member <= DISPID_BASE) + if (member <= DISPID_BASE_METHOD) { hr = get_typeinfo( ISWbemObject_tid, &typeinfo ); if (SUCCEEDED(hr)) @@ -1044,6 +1095,7 @@ static HRESULT SWbemObject_create( IWbemClassObject *wbem_object, ISWbemObject * object->members = NULL; object->nb_members = 0; object->last_dispid = DISPID_BASE; + object->last_dispid_method = DISPID_BASE_METHOD;
*obj = &object->ISWbemObject_iface; TRACE( "returning iface %p\n", *obj ); diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index 1ce045697a..68c0e3b589 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -48,6 +48,11 @@ static void test_ParseDisplayName(void) static const WCHAR name4[] = {'w','i','n','m','g','m','t','s',':','\','\','.','\','r','o','o','t','\','c','i','m','v','2',':', 'W','i','n','3','2','_','S','e','r','v','i','c','e',0}; + static const WCHAR stdregprovW[] = + {'w','i','n','m','g','m','t','s',':','\','\','.','\','r','o','o','t','\','d','e','f','a','u','l','t',':', + 'S','t','d','R','e','g','P','r','o','v',0}; + static const WCHAR getstringvalueW[] = + {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0}; static const struct { const WCHAR *name; @@ -242,6 +247,36 @@ static void test_ParseDisplayName(void) }
IBindCtx_Release( ctx ); + + hr = CreateBindCtx( 0, &ctx ); + ok( hr == S_OK, "got %x\n", hr ); + + str = SysAllocString( stdregprovW ); + hr = IParseDisplayName_ParseDisplayName( displayname, NULL, str, &eaten, &moniker ); + ok( hr == S_OK, "got %x\n", hr ); + SysFreeString( str ); + + if (moniker) + { + ISWbemObject *sobj = NULL; + hr = IMoniker_BindToObject( moniker, ctx, NULL, &IID_ISWbemObject, (void **)&sobj ); + ok( hr == S_OK, "got %x\n",hr ); + if (sobj) + { + DISPID dispid = 0xdeadbeef; + + str = SysAllocString( getstringvalueW ); + hr = ISWbemObject_GetIDsOfNames( sobj, &IID_NULL, &str, 1, english, &dispid ); + ok( hr == S_OK, "got %x\n", hr ); + ok( dispid == 0x1000001, "got %x\n", dispid ); + + ISWbemObject_Release( sobj ); + SysFreeString( str ); + } + IMoniker_Release( moniker ); + } + + IBindCtx_Release(ctx); IParseDisplayName_Release( displayname ); }