Nikolay Sivov : wbemprox: Implement GetValue()/SetValue() for context object.

Alexandre Julliard julliard at winehq.org
Thu Feb 25 16:45:37 CST 2021


Module: wine
Branch: master
Commit: 377853dc512a48971f5e3fc6a18e7f43c0c7af04
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=377853dc512a48971f5e3fc6a18e7f43c0c7af04

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Thu Feb 25 10:04:30 2021 +0300

wbemprox: Implement GetValue()/SetValue() for context object.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 );
 }
 




More information about the wine-cvs mailing list