[PATCH] wbemprox: Implement StdRegProv.CreateKey.

Hans Leidekker hans at codeweavers.com
Fri Sep 28 03:58:40 CDT 2018


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/wbemprox/builtin.c          |  7 ++++-
 dlls/wbemprox/reg.c              | 61 ++++++++++++++++++++++++++++++++++++++++
 dlls/wbemprox/tests/query.c      | 42 +++++++++++++++++++++++++++
 dlls/wbemprox/wbemprox_private.h |  2 ++
 4 files changed, 111 insertions(+), 1 deletion(-)

diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index a695e7c516..3832540d4d 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -712,6 +712,7 @@ static const struct column col_sounddevice[] =
 };
 static const struct column col_stdregprov[] =
 {
+    { method_createkeyW,      CIM_FLAG_ARRAY|COL_FLAG_METHOD },
     { method_enumkeyW,        CIM_FLAG_ARRAY|COL_FLAG_METHOD },
     { method_enumvaluesW,     CIM_FLAG_ARRAY|COL_FLAG_METHOD },
     { method_getstringvalueW, CIM_FLAG_ARRAY|COL_FLAG_METHOD }
@@ -1135,6 +1136,7 @@ struct record_sounddevice
 };
 struct record_stdregprov
 {
+    class_method *createkey;
     class_method *enumkey;
     class_method *enumvalues;
     class_method *getstringvalue;
@@ -1199,6 +1201,9 @@ static const struct record_param data_param[] =
     { class_serviceW, method_resumeserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
     { class_serviceW, method_startserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
     { class_serviceW, method_stopserviceW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
+    { class_stdregprovW, method_createkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
+    { class_stdregprovW, method_createkeyW, 1, param_subkeynameW, CIM_STRING },
+    { class_stdregprovW, method_createkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
     { class_stdregprovW, method_enumkeyW, 1, param_defkeyW, CIM_SINT32, 0, 0x80000002 },
     { class_stdregprovW, method_enumkeyW, 1, param_subkeynameW, CIM_STRING },
     { class_stdregprovW, method_enumkeyW, -1, param_returnvalueW, CIM_UINT32, VT_I4 },
@@ -1237,7 +1242,7 @@ static const struct record_sounddevice data_sounddevice[] =
 };
 static const struct record_stdregprov data_stdregprov[] =
 {
-    { reg_enum_key, reg_enum_values, reg_get_stringvalue }
+    { reg_create_key, reg_enum_key, reg_enum_values, reg_get_stringvalue }
 };
 static UINT16 systemenclosure_chassistypes[] =
 {
diff --git a/dlls/wbemprox/reg.c b/dlls/wbemprox/reg.c
index 79440dac8d..ed30d15100 100644
--- a/dlls/wbemprox/reg.c
+++ b/dlls/wbemprox/reg.c
@@ -76,6 +76,67 @@ static HRESULT to_i4_array( DWORD *values, DWORD count, VARIANT *var )
     return S_OK;
 }
 
+static HRESULT create_key( HKEY root, const WCHAR *subkey, VARIANT *retval )
+{
+    LONG res;
+    HKEY hkey;
+
+    TRACE("%p, %s\n", root, debugstr_w(subkey));
+
+    res = RegCreateKeyExW( root, subkey, 0, NULL, 0, 0, NULL, &hkey, NULL );
+    set_variant( VT_UI4, res, NULL, retval );
+    if (!res)
+    {
+        RegCloseKey( hkey );
+        return S_OK;
+    }
+    return HRESULT_FROM_WIN32( res );
+}
+
+HRESULT reg_create_key( IWbemClassObject *obj, IWbemClassObject *in, IWbemClassObject **out )
+{
+    VARIANT defkey, subkey, retval;
+    IWbemClassObject *sig, *out_params = NULL;
+    HRESULT hr;
+
+    TRACE("%p, %p\n", in, out);
+
+    hr = IWbemClassObject_Get( in, param_defkeyW, 0, &defkey, NULL, NULL );
+    if (hr != S_OK) return hr;
+    hr = IWbemClassObject_Get( in, param_subkeynameW, 0, &subkey, NULL, NULL );
+    if (hr != S_OK) return hr;
+
+    hr = create_signature( class_stdregprovW, method_createkeyW, PARAM_OUT, &sig );
+    if (hr != S_OK)
+    {
+        VariantClear( &subkey );
+        return hr;
+    }
+    if (out)
+    {
+        hr = IWbemClassObject_SpawnInstance( sig, 0, &out_params );
+        if (hr != S_OK)
+        {
+            VariantClear( &subkey );
+            IWbemClassObject_Release( sig );
+            return hr;
+        }
+    }
+    hr = create_key( (HKEY)(INT_PTR)V_I4(&defkey), V_BSTR(&subkey), &retval );
+    if (hr == S_OK && out_params)
+        hr = IWbemClassObject_Put( out_params, param_returnvalueW, 0, &retval, CIM_UINT32 );
+
+    VariantClear( &subkey );
+    IWbemClassObject_Release( sig );
+    if (hr == S_OK && out)
+    {
+        *out = out_params;
+        IWbemClassObject_AddRef( out_params );
+    }
+    if (out_params) IWbemClassObject_Release( out_params );
+    return hr;
+}
+
 static HRESULT enum_key( HKEY root, const WCHAR *subkey, VARIANT *names, VARIANT *retval )
 {
     HKEY hkey;
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c
index 39b6ba9c95..26e2dfa30d 100644
--- a/dlls/wbemprox/tests/query.c
+++ b/dlls/wbemprox/tests/query.c
@@ -704,6 +704,7 @@ static void test_Win32_SystemEnclosure( IWbemServices *services )
 
 static void test_StdRegProv( IWbemServices *services )
 {
+    static const WCHAR createkeyW[] = {'C','r','e','a','t','e','K','e','y',0};
     static const WCHAR enumkeyW[] = {'E','n','u','m','K','e','y',0};
     static const WCHAR enumvaluesW[] = {'E','n','u','m','V','a','l','u','e','s',0};
     static const WCHAR getstringvalueW[] = {'G','e','t','S','t','r','i','n','g','V','a','l','u','e',0};
@@ -719,11 +720,14 @@ static void test_StdRegProv( IWbemServices *services )
     static const WCHAR windowsW[] =
         {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
          'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
+    static const WCHAR regtestW[] =
+        {'S','o','f','t','w','a','r','e','\\','S','t','d','R','e','g','P','r','o','v','T','e','s','t',0};
     BSTR class = SysAllocString( stdregprovW ), method;
     IWbemClassObject *reg, *sig_in, *in, *out;
     VARIANT defkey, subkey, retval, names, types, value, valuename;
     CIMTYPE type;
     HRESULT hr;
+    LONG res;
 
     hr = IWbemServices_GetObject( services, class, 0, NULL, &reg, NULL );
     if (hr != S_OK)
@@ -731,6 +735,44 @@ static void test_StdRegProv( IWbemServices *services )
         win_skip( "StdRegProv not available\n" );
         return;
     }
+    hr = IWbemClassObject_GetMethod( reg, createkeyW, 0, &sig_in, NULL );
+    ok( hr == S_OK, "failed to get CreateKey method %08x\n", hr );
+
+    hr = IWbemClassObject_SpawnInstance( sig_in, 0, &in );
+    ok( hr == S_OK, "failed to spawn instance %08x\n", hr );
+
+    V_VT( &defkey ) = VT_I4;
+    V_I4( &defkey ) = 0x80000001;
+    hr = IWbemClassObject_Put( in, defkeyW, 0, &defkey, 0 );
+    ok( hr == S_OK, "failed to set root %08x\n", hr );
+
+    V_VT( &subkey ) = VT_BSTR;
+    V_BSTR( &subkey ) = SysAllocString( regtestW );
+    hr = IWbemClassObject_Put( in, subkeynameW, 0, &subkey, 0 );
+    ok( hr == S_OK, "failed to set subkey %08x\n", hr );
+
+    out = NULL;
+    method = SysAllocString( createkeyW );
+    hr = IWbemServices_ExecMethod( services, class, method, 0, NULL, in, &out, NULL );
+    ok( hr == S_OK, "failed to execute method %08x\n", hr );
+    SysFreeString( method );
+
+    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_UI4( &retval ) );
+    ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+
+    res = RegDeleteKeyW( HKEY_CURRENT_USER, regtestW );
+    ok( !res, "got %d\n", res );
+
+    VariantClear( &subkey );
+    IWbemClassObject_Release( in );
+    IWbemClassObject_Release( out );
+    IWbemClassObject_Release( sig_in );
+
     hr = IWbemClassObject_GetMethod( reg, enumkeyW, 0, &sig_in, NULL );
     ok( hr == S_OK, "failed to get EnumKey method %08x\n", hr );
 
diff --git a/dlls/wbemprox/wbemprox_private.h b/dlls/wbemprox/wbemprox_private.h
index 54b1ba3d8e..83776c8df7 100644
--- a/dlls/wbemprox/wbemprox_private.h
+++ b/dlls/wbemprox/wbemprox_private.h
@@ -218,6 +218,7 @@ HRESULT EnumWbemClassObject_create(struct query *, LPVOID *) DECLSPEC_HIDDEN;
 HRESULT WbemQualifierSet_create(const WCHAR *, const WCHAR *, LPVOID *) DECLSPEC_HIDDEN;
 
 HRESULT process_get_owner(IWbemClassObject *, IWbemClassObject *, IWbemClassObject **) DECLSPEC_HIDDEN;
+HRESULT reg_create_key(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;
@@ -243,6 +244,7 @@ static const WCHAR class_systemsecurityW[] = {'_','_','S','y','s','t','e','m','S
 
 static const WCHAR prop_nameW[] = {'N','a','m','e',0};
 
+static const WCHAR method_createkeyW[] = {'C','r','e','a','t','e','K','e','y',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};
-- 
2.11.0




More information about the wine-devel mailing list