Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/wbemprox/services.c | 87 +++++++++++++++++++++++++++++++--- dlls/wbemprox/tests/services.c | 63 ++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 6 deletions(-)
diff --git a/dlls/wbemprox/services.c b/dlls/wbemprox/services.c index 965f1b168f1..eff5148ef29 100644 --- a/dlls/wbemprox/services.c +++ b/dlls/wbemprox/services.c @@ -955,12 +955,33 @@ HRESULT WbemServices_create( const WCHAR *namespace, LPVOID *ppObj ) return S_OK; }
+struct wbem_context_value +{ + struct list entry; + WCHAR *name; + VARIANT value; +}; + struct wbem_context { IWbemContext IWbemContext_iface; LONG refs; + struct list values; };
+static void wbem_context_delete_values(struct wbem_context *context) +{ + struct wbem_context_value *value, *next; + + LIST_FOR_EACH_ENTRY_SAFE(value, next, &context->values, struct wbem_context_value, entry) + { + list_remove( &value->entry ); + VariantClear( &value->value ); + heap_free( value->name ); + heap_free( value ); + } +} + static struct wbem_context *impl_from_IWbemContext( IWbemContext *iface ) { return CONTAINING_RECORD( iface, struct wbem_context, IWbemContext_iface ); @@ -1004,6 +1025,7 @@ static ULONG WINAPI wbem_context_Release( if (!refs) { TRACE("destroying %p\n", context); + wbem_context_delete_values( context ); heap_free( context ); } return refs; @@ -1056,26 +1078,78 @@ static HRESULT WINAPI wbem_context_EndEnumeration( return E_NOTIMPL; }
+static struct wbem_context_value *wbem_context_get_value( struct wbem_context *context, const WCHAR *name ) +{ + struct wbem_context_value *value; + + LIST_FOR_EACH_ENTRY( value, &context->values, struct wbem_context_value, entry ) + { + if (!lstrcmpiW( value->name, name )) return value; + } + + return NULL; +} + static HRESULT WINAPI wbem_context_SetValue( IWbemContext *iface, LPCWSTR name, LONG flags, - VARIANT *value ) + VARIANT *var ) { - FIXME("%p, %s, %#x, %p\n", iface, debugstr_w(name), flags, value); + struct wbem_context *context = impl_from_IWbemContext( iface ); + struct wbem_context_value *value; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %s, %#x, %s\n", iface, debugstr_w(name), flags, debugstr_variant(var)); + + if (!name || !var) + return WBEM_E_INVALID_PARAMETER; + + if ((value = wbem_context_get_value( context, name ))) + { + VariantClear( &value->value ); + hr = VariantCopy( &value->value, var ); + } + else + { + if (!(value = heap_alloc_zero( sizeof(*value) ))) return E_OUTOFMEMORY; + if (!(value->name = heap_strdupW( name ))) + { + heap_free( value ); + return E_OUTOFMEMORY; + } + if (FAILED(hr = VariantCopy( &value->value, var ))) + { + heap_free( value->name ); + heap_free( value ); + return hr; + } + + list_add_tail( &context->values, &value->entry ); + } + + return hr; }
static HRESULT WINAPI wbem_context_GetValue( IWbemContext *iface, LPCWSTR name, LONG flags, - VARIANT *value ) + VARIANT *var ) { - FIXME("%p, %s, %#x, %p\n", iface, debugstr_w(name), flags, value); + struct wbem_context *context = impl_from_IWbemContext( iface ); + struct wbem_context_value *value;
- return E_NOTIMPL; + TRACE("%p, %s, %#x, %p\n", iface, debugstr_w(name), flags, var); + + if (!name || !var) + return WBEM_E_INVALID_PARAMETER; + + if (!(value = wbem_context_get_value( context, name ))) + return WBEM_E_NOT_FOUND; + + V_VT(var) = VT_EMPTY; + return VariantCopy( var, &value->value ); }
static HRESULT WINAPI wbem_context_DeleteValue( @@ -1123,6 +1197,7 @@ HRESULT WbemContext_create( void **obj )
context->IWbemContext_iface.lpVtbl = &wbem_context_vtbl; context->refs = 1; + list_init(&context->values);
*obj = &context->IWbemContext_iface;
diff --git a/dlls/wbemprox/tests/services.c b/dlls/wbemprox/tests/services.c index a60d39f1ef2..ebbc766d6c5 100644 --- a/dlls/wbemprox/tests/services.c +++ b/dlls/wbemprox/tests/services.c @@ -152,11 +152,74 @@ static void test_IWbemLocator(void) static void test_IWbemContext(void) { IWbemContext *context; + VARIANT var; HRESULT hr; + BSTR str;
hr = CoCreateInstance( &CLSID_WbemContext, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemContext, (void **)&context ); ok(hr == S_OK, "Failed to create context object, hr %#x.\n", hr);
+ hr = IWbemContext_SetValue(context, L"name", 0, NULL); + ok(hr == WBEM_E_INVALID_PARAMETER, "Unexpected hr %#x.\n", hr); + + V_VT(&var) = VT_I4; + V_I4(&var) = 12; + hr = IWbemContext_SetValue(context, NULL, 0, &var); + ok(hr == WBEM_E_INVALID_PARAMETER, "Unexpected hr %#x.\n", hr); + + hr = IWbemContext_SetValue(context, L"name", 0, &var); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IWbemContext_GetValue(context, NULL, 0, &var); + ok(hr == WBEM_E_INVALID_PARAMETER, "Unexpected hr %#x.\n", hr); + + hr = IWbemContext_GetValue(context, L"name", 0, NULL); + ok(hr == WBEM_E_INVALID_PARAMETER, "Unexpected hr %#x.\n", hr); + + hr = IWbemContext_GetValue(context, L"noname", 0, &var); + ok(hr == WBEM_E_NOT_FOUND, "Unexpected hr %#x.\n", hr); + + V_VT(&var) = VT_EMPTY; + hr = IWbemContext_GetValue(context, L"NAME", 0, &var); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(V_VT(&var) == VT_I4, "Unexpected value type.\n"); + + V_VT(&var) = VT_I4; + V_I4(&var) = 13; + hr = IWbemContext_SetValue(context, L"name2", 0, &var); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IWbemContext_Next(context, 0, &str, &var); +todo_wine + ok(hr == WBEM_E_UNEXPECTED, "Unexpected hr %#x.\n", hr); + + hr = IWbemContext_BeginEnumeration(context, 0); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + str = NULL; + hr = IWbemContext_Next(context, 0, &str, &var); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!lstrcmpW(str, L"name"), "Unexpected name %s.\n", wine_dbgstr_w(str)); + SysFreeString(str); +} + hr = IWbemContext_EndEnumeration(context); +todo_wine + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Overwrite */ + V_VT(&var) = VT_I4; + V_I4(&var) = 14; + hr = IWbemContext_SetValue(context, L"name", 0, &var); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + V_VT(&var) = VT_EMPTY; + hr = IWbemContext_GetValue(context, L"name", 0, &var); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(V_VT(&var) == VT_I4, "Unexpected value type.\n"); + ok(V_I4(&var) == 14, "Unexpected value.\n"); + IWbemContext_Release( context ); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/wbemdisp/locator.c | 241 +++++++++++++++++++++++++++++++-- dlls/wbemdisp/tests/wbemdisp.c | 76 +++++++++++ 2 files changed, 308 insertions(+), 9 deletions(-)
diff --git a/dlls/wbemdisp/locator.c b/dlls/wbemdisp/locator.c index bbb0625f4e8..1d61c423a91 100644 --- a/dlls/wbemdisp/locator.c +++ b/dlls/wbemdisp/locator.c @@ -48,6 +48,7 @@ enum type_id ISWbemServices_tid, ISWbemSecurity_tid, ISWbemNamedValueSet_tid, + ISWbemNamedValue_tid, last_tid };
@@ -64,6 +65,7 @@ static REFIID wbemdisp_tid_id[] = &IID_ISWbemServices, &IID_ISWbemSecurity, &IID_ISWbemNamedValueSet, + &IID_ISWbemNamedValue, };
static HRESULT get_typeinfo( enum type_id tid, ITypeInfo **ret ) @@ -2463,6 +2465,14 @@ struct namedvalueset { ISWbemNamedValueSet ISWbemNamedValueSet_iface; LONG refs; + + IWbemContext *context; +}; + +struct namedvalue +{ + ISWbemNamedValue ISWbemNamedValue_iface; + LONG refs; };
static struct namedvalueset *impl_from_ISWbemNamedValueSet( ISWbemNamedValueSet *iface ) @@ -2470,6 +2480,188 @@ static struct namedvalueset *impl_from_ISWbemNamedValueSet( ISWbemNamedValueSet return CONTAINING_RECORD( iface, struct namedvalueset, ISWbemNamedValueSet_iface ); }
+static struct namedvalue *impl_from_ISWbemNamedValue( ISWbemNamedValue *iface ) +{ + return CONTAINING_RECORD( iface, struct namedvalue, ISWbemNamedValue_iface ); +} + +static HRESULT WINAPI namedvalue_QueryInterface( + ISWbemNamedValue *iface, + REFIID riid, + void **ppvObject ) +{ + struct namedvalue *value = impl_from_ISWbemNamedValue( iface ); + + TRACE( "%p, %s, %p\n", value, debugstr_guid( riid ), ppvObject ); + + if (IsEqualGUID( riid, &IID_ISWbemNamedValue ) || + IsEqualGUID( riid, &IID_IDispatch ) || + IsEqualGUID( riid, &IID_IUnknown )) + { + *ppvObject = iface; + } + else + { + FIXME( "interface %s not implemented\n", debugstr_guid(riid) ); + return E_NOINTERFACE; + } + ISWbemNamedValue_AddRef( iface ); + return S_OK; +} + +static ULONG WINAPI namedvalue_AddRef( + ISWbemNamedValue *iface ) +{ + struct namedvalue *value = impl_from_ISWbemNamedValue( iface ); + return InterlockedIncrement( &value->refs ); +} + +static ULONG WINAPI namedvalue_Release( + ISWbemNamedValue *iface ) +{ + struct namedvalue *value = impl_from_ISWbemNamedValue( iface ); + LONG refs = InterlockedDecrement( &value->refs ); + if (!refs) + { + TRACE( "destroying %p\n", value ); + heap_free( value ); + } + return refs; +} + +static HRESULT WINAPI namedvalue_GetTypeInfoCount( + ISWbemNamedValue *iface, + UINT *count ) +{ + struct namedvalue *value = impl_from_ISWbemNamedValue( iface ); + TRACE( "%p, %p\n", value, count ); + + *count = 1; + return S_OK; +} + +static HRESULT WINAPI namedvalue_GetTypeInfo( + ISWbemNamedValue *iface, + UINT index, + LCID lcid, + ITypeInfo **info ) +{ + struct namedvalue *value = impl_from_ISWbemNamedValue( iface ); + + TRACE( "%p, %u, %u, %p\n", value, index, lcid, info ); + + return get_typeinfo( ISWbemNamedValue_tid, info ); +} + +static HRESULT WINAPI namedvalue_GetIDsOfNames( + ISWbemNamedValue *iface, + REFIID riid, + LPOLESTR *names, + UINT count, + LCID lcid, + DISPID *dispid ) +{ + struct namedvalue *value = impl_from_ISWbemNamedValue( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %s, %p, %u, %u, %p\n", value, debugstr_guid(riid), names, count, lcid, dispid ); + + if (!names || !count || !dispid) return E_INVALIDARG; + + hr = get_typeinfo( ISWbemNamedValue_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI namedvalue_Invoke( + ISWbemNamedValue *iface, + DISPID member, + REFIID riid, + LCID lcid, + WORD flags, + DISPPARAMS *params, + VARIANT *result, + EXCEPINFO *excep_info, + UINT *arg_err ) +{ + struct namedvalue *set = impl_from_ISWbemNamedValue( iface ); + ITypeInfo *typeinfo; + HRESULT hr; + + TRACE( "%p, %d, %s, %d, %d, %p, %p, %p, %p\n", set, member, debugstr_guid(riid), + lcid, flags, params, result, excep_info, arg_err ); + + hr = get_typeinfo( ISWbemNamedValue_tid, &typeinfo ); + if (SUCCEEDED(hr)) + { + hr = ITypeInfo_Invoke( typeinfo, &set->ISWbemNamedValue_iface, member, flags, + params, result, excep_info, arg_err ); + ITypeInfo_Release( typeinfo ); + } + return hr; +} + +static HRESULT WINAPI namedvalue_get_Value( + ISWbemNamedValue *iface, + VARIANT *var ) +{ + FIXME("\n"); + + return E_NOTIMPL; +} + +static HRESULT WINAPI namedvalue_put_Value( + ISWbemNamedValue *iface, + VARIANT *var ) +{ + FIXME("\n"); + + return E_NOTIMPL; +} + +static HRESULT WINAPI namedvalue_get_Name( + ISWbemNamedValue *iface, + BSTR *name ) +{ + FIXME("\n"); + + return E_NOTIMPL; +} + +static const ISWbemNamedValueVtbl namedvaluevtbl = +{ + namedvalue_QueryInterface, + namedvalue_AddRef, + namedvalue_Release, + namedvalue_GetTypeInfoCount, + namedvalue_GetTypeInfo, + namedvalue_GetIDsOfNames, + namedvalue_Invoke, + namedvalue_get_Value, + namedvalue_put_Value, + namedvalue_get_Name +}; + +static HRESULT namedvalue_create( ISWbemNamedValue **value ) +{ + struct namedvalue *object; + + if (!(object = heap_alloc(sizeof(*object)))) + return E_OUTOFMEMORY; + + object->ISWbemNamedValue_iface.lpVtbl = &namedvaluevtbl; + object->refs = 1; + + *value = &object->ISWbemNamedValue_iface; + + return S_OK; +} + static HRESULT WINAPI namedvalueset_QueryInterface( ISWbemNamedValueSet *iface, REFIID riid, @@ -2509,6 +2701,8 @@ static ULONG WINAPI namedvalueset_Release( if (!refs) { TRACE( "destroying %p\n", set ); + if (set->context) + IWbemContext_Release( set->context ); heap_free( set ); } return refs; @@ -2606,12 +2800,22 @@ static HRESULT WINAPI namedvalueset_Item( LONG flags, ISWbemNamedValue **value ) { - FIXME("\n"); + struct namedvalueset *set = impl_from_ISWbemNamedValueSet( iface ); + VARIANT var; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %s, %#x, %p\n", set, debugstr_w(name), flags, value); + + if (SUCCEEDED(hr = IWbemContext_GetValue( set->context, name, flags, &var ))) + { + VariantClear( &var ); + hr = namedvalue_create( value ); + } + + return hr; }
-static HRESULT WINAPI namedvalueset_Count( +static HRESULT WINAPI namedvalueset_get_Count( ISWbemNamedValueSet *iface, LONG *count ) { @@ -2623,13 +2827,24 @@ static HRESULT WINAPI namedvalueset_Count( static HRESULT WINAPI namedvalueset_Add( ISWbemNamedValueSet *iface, BSTR name, - VARIANT *value, + VARIANT *var, LONG flags, - ISWbemNamedValue **namedvalue ) + ISWbemNamedValue **value ) { - FIXME("\n"); + struct namedvalueset *set = impl_from_ISWbemNamedValueSet( iface ); + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %s, %s, %#x, %p\n", set, debugstr_w(name), debugstr_variant(var), flags, value); + + if (!name || !var || !value) + return WBEM_E_INVALID_PARAMETER; + + if (SUCCEEDED(hr = IWbemContext_SetValue( set->context, name, flags, var ))) + { + hr = namedvalue_create( value ); + } + + return hr; }
static HRESULT WINAPI namedvalueset_Remove( @@ -2670,7 +2885,7 @@ static const ISWbemNamedValueSetVtbl namedvalueset_vtbl = namedvalueset_Invoke, namedvalueset_get__NewEnum, namedvalueset_Item, - namedvalueset_Count, + namedvalueset_get_Count, namedvalueset_Add, namedvalueset_Remove, namedvalueset_Clone, @@ -2680,6 +2895,7 @@ static const ISWbemNamedValueSetVtbl namedvalueset_vtbl = HRESULT SWbemNamedValueSet_create( void **obj ) { struct namedvalueset *set; + HRESULT hr;
TRACE( "%p\n", obj );
@@ -2687,7 +2903,14 @@ HRESULT SWbemNamedValueSet_create( void **obj ) set->ISWbemNamedValueSet_iface.lpVtbl = &namedvalueset_vtbl; set->refs = 1;
+ if (FAILED(hr = CoCreateInstance( &CLSID_WbemContext, NULL, CLSCTX_INPROC_SERVER, &IID_IWbemContext, + (void **)&set->context ))) + { + ISWbemNamedValueSet_Release( &set->ISWbemNamedValueSet_iface ); + return hr; + } + *obj = &set->ISWbemNamedValueSet_iface; TRACE( "returning iface %p\n", *obj ); - return S_OK; + return hr; } diff --git a/dlls/wbemdisp/tests/wbemdisp.c b/dlls/wbemdisp/tests/wbemdisp.c index 24225ad1ac1..c38a0f14c9b 100644 --- a/dlls/wbemdisp/tests/wbemdisp.c +++ b/dlls/wbemdisp/tests/wbemdisp.c @@ -404,12 +404,88 @@ static void test_locator(void)
static void test_namedvalueset(void) { + static const WCHAR nameW[] = {'n','a','m','e',0,'2'}; + ISWbemNamedValue *value, *value2; ISWbemNamedValueSet *set; + VARIANT var; HRESULT hr; + BSTR name; + LONG count;
hr = CoCreateInstance( &CLSID_SWbemNamedValueSet, NULL, CLSCTX_INPROC_SERVER, &IID_ISWbemNamedValueSet, (void **)&set ); ok( hr == S_OK, "got %x\n", hr );
+ name = SysAllocString( L"name" ); + V_VT(&var) = VT_I4; + V_I4(&var) = 10; + + hr = ISWbemNamedValueSet_Add( set, name, &var, 0, NULL ); + ok( hr == WBEM_E_INVALID_PARAMETER, "Unexpected hr %#x.\n", hr ); + + hr = ISWbemNamedValueSet_Add( set, name, &var, 0, &value ); + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + + /* New instance is returned, referencing same entry. */ + hr = ISWbemNamedValueSet_Item( set, name, 0, &value2 ); + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + ok( value != value2, "Unexpected value instance.\n" ); + + V_I4(&var) = 20; + hr = ISWbemNamedValue_put_Value( value2, &var ); +todo_wine + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + + V_I4(&var) = 0; + hr = ISWbemNamedValue_get_Value( value, &var ); +todo_wine { + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + ok( V_I4(&var) == 20, "Unexpected value %d.\n", V_I4(&var) ); +} + ISWbemNamedValue_Release( value ); + ISWbemNamedValue_Release( value2 ); + + SysFreeString( name ); + + /* Embedded nulls in names */ + name = SysAllocStringLen(nameW, ARRAY_SIZE(nameW)); + hr = ISWbemNamedValueSet_Item( set, name, 0, &value ); + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + ISWbemNamedValue_Release( value ); + + V_I4(&var) = 11; + hr = ISWbemNamedValueSet_Add( set, name, &var, 0, &value ); + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + + count = 0; + hr = ISWbemNamedValueSet_get_Count( set, &count ); +todo_wine { + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + ok( count == 1, "Unexpected count %d.\n", count ); +} + hr = ISWbemNamedValueSet_DeleteAll( set ); +todo_wine + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + + count = 1; + hr = ISWbemNamedValueSet_get_Count( set, &count ); +todo_wine { + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + ok( count == 0, "Unexpected count %d.\n", count ); +} + V_I4(&var) = 20; + hr = ISWbemNamedValue_put_Value( value, &var ); +todo_wine + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + + count = 0; + hr = ISWbemNamedValueSet_get_Count( set, &count ); +todo_wine { + ok( hr == S_OK, "Unexpected hr %#x.\n", hr ); + ok( count == 1, "Unexpected count %d.\n", count ); +} + ISWbemNamedValue_Release( value ); + SysFreeString( name ); + ISWbemNamedValueSet_Release(set); }
Signed-off-by: Hans Leidekker hans@codeweavers.com