[PATCH v3 1/3] msdasql: Implement ICommandProperties GetProperties

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Sat Nov 27 22:03:08 CST 2021


Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/msdasql/msdasql_main.c   |   1 +
 dlls/msdasql/session.c        | 216 +++++++++++++++++++++++++++++++++-
 dlls/msdasql/tests/provider.c | 145 +++++++++++++++++++++++
 3 files changed, 360 insertions(+), 2 deletions(-)

diff --git a/dlls/msdasql/msdasql_main.c b/dlls/msdasql/msdasql_main.c
index bc208a74cc5..84afdb06145 100644
--- a/dlls/msdasql/msdasql_main.c
+++ b/dlls/msdasql/msdasql_main.c
@@ -37,6 +37,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msdasql);
 
 DEFINE_GUID(DBPROPSET_DATASOURCEINFO, 0xc8b522bb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 DEFINE_GUID(DBPROPSET_DBINIT,    0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
+DEFINE_GUID(DBPROPSET_ROWSET,    0xc8b522be, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 
 DEFINE_GUID(DBGUID_DEFAULT,      0xc8b521fb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 
diff --git a/dlls/msdasql/session.c b/dlls/msdasql/session.c
index b4239c59037..9f5c6ef4a53 100644
--- a/dlls/msdasql/session.c
+++ b/dlls/msdasql/session.c
@@ -35,6 +35,102 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(msdasql);
 
+struct msdasql_prop
+{
+    DBPROPID    property_id;
+    DBPROPFLAGS flags;
+    VARTYPE     vartype;
+
+    LONG value;
+};
+
+static struct msdasql_prop msdasql_init_props[] =
+{
+    { DBPROP_ABORTPRESERVE,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_DATASOURCEINFO, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_BLOCKINGSTORAGEOBJECTS,          DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_BOOKMARKS,                       DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_BOOKMARKSKIPPED,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_BOOKMARKTYPE,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4, 1 },
+    { DBPROP_CANFETCHBACKWARDS,               DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_CANHOLDROWS,                     DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_CANSCROLLBACKWARDS,              DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_COLUMNRESTRICT,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_COMMITPRESERVE,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_DELAYSTORAGEOBJECTS,             DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IMMOBILEROWS,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_LITERALBOOKMARKS,                DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_LITERALIDENTITY,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_MAXOPENROWS,                     DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4, 0 },
+    { DBPROP_MAXPENDINGROWS,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4,  0 },
+    { DBPROP_MAXROWS,                         DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4, 0 },
+    { DBPROP_NOTIFICATIONPHASES,              DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4, 31 },
+    { DBPROP_OTHERUPDATEDELETE,               DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_OWNINSERT,                       DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_OWNUPDATEDELETE,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_QUICKRESTART ,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_REENTRANTEVENTS,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_REMOVEDELETED,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_REPORTMULTIPLECHANGES,           DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_ROWRESTRICT,                     DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_ROWTHREADMODEL,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4, 2 },
+    { DBPROP_TRANSACTEDOBJECT,                DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_UPDATABILITY,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4, 0 },
+    { DBPROP_STRONGIDENTITY,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IAccessor,                       DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_IColumnsInfo,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_IColumnsRowset,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_IConnectionPointContainer,       DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowset,                         DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_IRowsetChange,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowsetIdentity,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowsetInfo,                     DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_IRowsetLocate,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowsetResynch,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowsetUpdate,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_ISupportErrorInfo,               DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_ISequentialStream,               DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_NOTIFYCOLUMNSET,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWDELETE,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWFIRSTCHANGE,            DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWINSERT,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWRESYNCH,                DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWSETRELEASE,             DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE, DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWUNDOCHANGE,             DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWUNDODELETE,             DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWUNDOINSERT,             DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_NOTIFYROWUPDATE,                 DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4,  3 },
+    { DBPROP_CHANGEINSERTEDROWS,              DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_RETURNPENDINGINSERTS,            DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IConvertType,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_NOTIFICATIONGRANULARITY,         DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4, 1 },
+    { DBPROP_IMultipleResults,                DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_ACCESSORDER,                     DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4, 1 },
+    { DBPROP_BOOKMARKINFO,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4, 0 },
+    { DBPROP_UNIQUEROWS,                      DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowsetFind,                     DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_IRowsetScroll,                   DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_IRowsetRefresh,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_FINDCOMPAREOPS,                  DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ, VT_I4, 27 },
+    { DBPROP_ORDEREDBOOKMARKS,                DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_CLIENTCURSOR,                    DBPROPFLAGS_ROWSET | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_TRUE },
+    { DBPROP_ABORTPRESERVE,                   DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_ACTIVESESSIONS,                  DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_ASYNCTXNCOMMIT,                  DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_AUTH_CACHE_AUTHINFO,             DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_AUTH_ENCRYPT_PASSWORD,           DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4, 0 },
+    { DBPROP_AUTH_INTEGRATED,                 DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_I4, 14 },
+    { DBPROP_AUTH_MASK_PASSWORD,              DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_AUTH_PASSWORD,                   DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_AUTH_PERSIST_ENCRYPTED,          DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_AUTH_USERID,                     DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+    { DBPROP_BLOCKINGSTORAGEOBJECTS,          DBPROPFLAGS_DATASOURCEINFO | DBPROPFLAGS_READ | DBPROPFLAGS_WRITE, VT_BOOL, VARIANT_FALSE },
+};
+
+#define ROWSET_PROP_COUNT 68
+#define DATASOURCE_PROP_COUNT 12
+
 struct msdasql_session
 {
     IUnknown session_iface;
@@ -305,6 +401,8 @@ struct command
     LONG refs;
     WCHAR *query;
     IUnknown *session;
+
+    struct msdasql_prop properties[80];
 };
 
 static inline struct command *impl_from_ICommandText( ICommandText *iface )
@@ -933,8 +1031,120 @@ static HRESULT WINAPI command_prop_GetProperties(ICommandProperties *iface, ULON
         const DBPROPIDSET propertyidsets[], ULONG *sets_cnt, DBPROPSET **propertyset)
 {
     struct command *command = impl_from_ICommandProperties( iface );
-    FIXME("%p %d %p %p %p\n", command, count, propertyidsets, sets_cnt, propertyset);
-    return E_NOTIMPL;
+    DBPROPSET *propset = NULL;
+    int i, j, k;
+
+    TRACE("%p %d %p %p %p\n", command, count, propertyidsets, sets_cnt, propertyset);
+
+    /* All Properties */
+    if (count == 0)
+    {
+        propset = CoTaskMemAlloc(2 * sizeof(DBPROPSET));
+        if (!propset)
+            return E_OUTOFMEMORY;
+
+        propset[0].guidPropertySet = DBPROPSET_ROWSET;
+        propset[0].cProperties = ROWSET_PROP_COUNT;
+        propset[0].rgProperties = CoTaskMemAlloc(propset[0].cProperties * sizeof(DBPROP));
+        if (!propset[0].rgProperties)
+        {
+            CoTaskMemFree(propset);
+            return E_OUTOFMEMORY;
+        }
+
+        for (j=0; j < propset[0].cProperties; j++)
+        {
+            propset[0].rgProperties[j].dwPropertyID = command->properties[j].property_id;
+
+            V_VT(&propset[0].rgProperties[j].vValue) = command->properties[j].vartype;
+            if (command->properties[j].vartype == VT_BOOL)
+            {
+                V_BOOL(&propset[0].rgProperties[j].vValue) = command->properties[j].value;
+            }
+            else if (command->properties[j].vartype == VT_I4)
+            {
+                V_I4(&propset[0].rgProperties[j].vValue) = command->properties[j].value;
+            }
+            else
+                ERR("Unknown variant type %d\n", command->properties[j].vartype);
+        }
+
+        propset[1].guidPropertySet = DBPROPSET_PROVIDERROWSET;
+        propset[1].cProperties = DATASOURCE_PROP_COUNT;
+        propset[1].rgProperties = CoTaskMemAlloc(propset[1].cProperties * sizeof(DBPROP));
+        if (!propset[1].rgProperties)
+        {
+            CoTaskMemFree(propset[0].rgProperties);
+            CoTaskMemFree(propset);
+            return E_OUTOFMEMORY;
+        }
+
+        i=0;
+        for (j=ROWSET_PROP_COUNT; j < ROWSET_PROP_COUNT+propset[1].cProperties; j++)
+        {
+            propset[1].rgProperties[i].dwPropertyID = command->properties[j].property_id;
+
+            V_VT(&propset[1].rgProperties[i].vValue) = command->properties[j].vartype;
+            if (command->properties[j].vartype == VT_BOOL)
+            {
+                V_BOOL(&propset[1].rgProperties[i].vValue) = command->properties[j].value;
+            }
+            else if (command->properties[j].vartype == VT_I4)
+            {
+                V_I4(&propset[1].rgProperties[i].vValue) = command->properties[j].value;
+            }
+            else
+                ERR("Unknown variant type %d\n", command->properties[j].vartype);
+            i++;
+        }
+
+        *sets_cnt = 2;
+    }
+    else
+    {
+        propset = CoTaskMemAlloc(count * sizeof(DBPROPSET));
+        if (!propset)
+            return E_OUTOFMEMORY;
+
+        for (i=0; i < count; i++)
+        {
+            TRACE("Property id %d (count %d, set %s)\n", i, propertyidsets[i].cPropertyIDs,
+                    debugstr_guid(&propertyidsets[i].guidPropertySet));
+
+            propset[i].cProperties = propertyidsets[i].cPropertyIDs;
+            propset[i].rgProperties = CoTaskMemAlloc(propset[i].cProperties * sizeof(DBPROP));
+
+            for (j=0; j < propset[i].cProperties; j++)
+            {
+                propset[i].rgProperties[j].dwPropertyID = propertyidsets[i].rgPropertyIDs[j];
+
+                for(k = 0; k < ARRAY_SIZE(command->properties); k++)
+                {
+                    if (command->properties[k].property_id == propertyidsets[i].rgPropertyIDs[j])
+                    {
+                        V_VT(&propset[i].rgProperties[i].vValue) = command->properties[j].vartype;
+                        if (command->properties[j].vartype == VT_BOOL)
+                        {
+                            V_BOOL(&propset[i].rgProperties[i].vValue) = command->properties[j].value;
+                        }
+                        else if (command->properties[j].vartype == VT_I4)
+                        {
+                            V_I4(&propset[i].rgProperties[i].vValue) = command->properties[j].value;
+                        }
+                        else
+                            ERR("Unknown variant type %d\n", command->properties[j].vartype);
+                        break;
+                    }
+                }
+            }
+        }
+
+        *sets_cnt = count;
+    }
+
+    *propertyset = propset;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI command_prop_SetProperties(ICommandProperties *iface, ULONG count,
@@ -1148,6 +1358,8 @@ static HRESULT WINAPI createcommand_CreateCommand(IDBCreateCommand *iface, IUnkn
     command->refs = 1;
     command->query = NULL;
 
+    memcpy(command->properties, msdasql_init_props, sizeof(msdasql_init_props));
+
     IUnknown_QueryInterface(&session->session_iface, &IID_IUnknown, (void**)&command->session);
 
     hr = ICommandText_QueryInterface(&command->ICommandText_iface, riid, (void**)out);
diff --git a/dlls/msdasql/tests/provider.c b/dlls/msdasql/tests/provider.c
index b520b127d67..211116dc382 100644
--- a/dlls/msdasql/tests/provider.c
+++ b/dlls/msdasql/tests/provider.c
@@ -34,6 +34,7 @@
 DEFINE_GUID(DBPROPSET_DATASOURCEINFO, 0xc8b522bb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 DEFINE_GUID(DBPROPSET_DBINITALL, 0xc8b522ca, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 DEFINE_GUID(DBPROPSET_DBINIT,    0xc8b522bc, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
+DEFINE_GUID(DBPROPSET_ROWSET,    0xc8b522be, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 
 DEFINE_GUID(DBGUID_DEFAULT,      0xc8b521fb, 0x5cf3, 0x11ce, 0xad, 0xe5, 0x00, 0xaa, 0x00, 0x44, 0x77, 0x3d);
 
@@ -183,6 +184,149 @@ static void test_Properties(void)
     IDBProperties_Release(props);
 }
 
+static void test_command_properties(ICommandProperties *props)
+{
+    HRESULT hr;
+    ULONG count;
+    DBPROPSET *propset;
+    int i;
+
+    DWORD row_props[68] = {
+            DBPROP_ABORTPRESERVE, DBPROP_BLOCKINGSTORAGEOBJECTS, DBPROP_BOOKMARKS, DBPROP_BOOKMARKSKIPPED,
+            DBPROP_BOOKMARKTYPE, DBPROP_CANFETCHBACKWARDS, DBPROP_CANHOLDROWS, DBPROP_CANSCROLLBACKWARDS,
+            DBPROP_COLUMNRESTRICT, DBPROP_COMMITPRESERVE, DBPROP_DELAYSTORAGEOBJECTS, DBPROP_IMMOBILEROWS,
+            DBPROP_LITERALBOOKMARKS, DBPROP_LITERALIDENTITY, DBPROP_MAXOPENROWS, DBPROP_MAXPENDINGROWS,
+            DBPROP_MAXROWS, DBPROP_NOTIFICATIONPHASES, DBPROP_OTHERUPDATEDELETE, DBPROP_OWNINSERT,
+            DBPROP_OWNUPDATEDELETE, DBPROP_QUICKRESTART, DBPROP_REENTRANTEVENTS, DBPROP_REMOVEDELETED,
+            DBPROP_REPORTMULTIPLECHANGES, DBPROP_ROWRESTRICT, DBPROP_ROWTHREADMODEL, DBPROP_TRANSACTEDOBJECT,
+            DBPROP_UPDATABILITY, DBPROP_STRONGIDENTITY, DBPROP_IAccessor, DBPROP_IColumnsInfo,
+            DBPROP_IColumnsRowset, DBPROP_IConnectionPointContainer, DBPROP_IRowset, DBPROP_IRowsetChange,
+            DBPROP_IRowsetIdentity, DBPROP_IRowsetInfo, DBPROP_IRowsetLocate, DBPROP_IRowsetResynch,
+            DBPROP_IRowsetUpdate, DBPROP_ISupportErrorInfo, DBPROP_ISequentialStream, DBPROP_NOTIFYCOLUMNSET,
+            DBPROP_NOTIFYROWDELETE, DBPROP_NOTIFYROWFIRSTCHANGE, DBPROP_NOTIFYROWINSERT, DBPROP_NOTIFYROWRESYNCH,
+            DBPROP_NOTIFYROWSETRELEASE, DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE, DBPROP_NOTIFYROWUNDOCHANGE, DBPROP_NOTIFYROWUNDODELETE,
+            DBPROP_NOTIFYROWUNDOINSERT, DBPROP_NOTIFYROWUPDATE, DBPROP_CHANGEINSERTEDROWS, DBPROP_RETURNPENDINGINSERTS,
+            DBPROP_IConvertType, DBPROP_NOTIFICATIONGRANULARITY, DBPROP_IMultipleResults, DBPROP_ACCESSORDER,
+            DBPROP_BOOKMARKINFO, DBPROP_UNIQUEROWS, DBPROP_IRowsetFind, DBPROP_IRowsetScroll,
+            DBPROP_IRowsetRefresh, DBPROP_FINDCOMPAREOPS, DBPROP_ORDEREDBOOKMARKS, DBPROP_CLIENTCURSOR
+    };
+
+    DWORD prov_props[12] = {
+            DBPROP_ABORTPRESERVE, DBPROP_ACTIVESESSIONS, DBPROP_ASYNCTXNCOMMIT, DBPROP_AUTH_CACHE_AUTHINFO,
+            DBPROP_AUTH_ENCRYPT_PASSWORD, DBPROP_AUTH_INTEGRATED, DBPROP_AUTH_MASK_PASSWORD, DBPROP_AUTH_PASSWORD,
+            DBPROP_AUTH_PERSIST_ENCRYPTED, DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO, DBPROP_AUTH_USERID, DBPROP_BLOCKINGSTORAGEOBJECTS
+    };
+
+    hr = ICommandProperties_GetProperties(props, 0, NULL, &count, &propset);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(count == 2, "got %d\n", count);
+    ok(propset[0].cProperties == 68, "got %d\n", propset[0].cProperties);
+    ok(propset[1].cProperties == 12, "got %d\n", propset[1].cProperties);
+
+    ok(IsEqualGUID(&DBPROPSET_ROWSET, &propset[0].guidPropertySet), "got %s\n",
+        debugstr_guid(&propset[0].guidPropertySet));
+    for (i = 0; i < propset[0].cProperties; i++)
+    {
+        ok(propset[0].rgProperties[i].dwPropertyID == row_props[i], "%d: got 0x%08x\n", i, propset[0].rgProperties[i].dwPropertyID);
+
+        switch(propset[0].rgProperties[i].dwPropertyID )
+        {
+            case DBPROP_BOOKMARKTYPE:
+            case DBPROP_NOTIFICATIONGRANULARITY:
+            case DBPROP_ACCESSORDER:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_I4(&propset[0].rgProperties[i].vValue) == 1, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            case DBPROP_MAXOPENROWS:
+            case DBPROP_MAXPENDINGROWS:
+            case DBPROP_MAXROWS:
+            case DBPROP_UPDATABILITY:
+            case DBPROP_BOOKMARKINFO:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_I4(&propset[0].rgProperties[i].vValue) == 0, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            case DBPROP_FINDCOMPAREOPS:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_I4(&propset[0].rgProperties[i].vValue) == 27, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            case DBPROP_NOTIFICATIONPHASES:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_I4(&propset[0].rgProperties[i].vValue) == 31, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            case DBPROP_ROWTHREADMODEL:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_I4(&propset[0].rgProperties[i].vValue) == 2, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            case DBPROP_NOTIFYCOLUMNSET:
+            case DBPROP_NOTIFYROWDELETE:
+            case DBPROP_NOTIFYROWFIRSTCHANGE:
+            case DBPROP_NOTIFYROWINSERT:
+            case DBPROP_NOTIFYROWRESYNCH:
+            case DBPROP_NOTIFYROWSETRELEASE:
+            case DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE:
+            case DBPROP_NOTIFYROWUNDOCHANGE:
+            case DBPROP_NOTIFYROWUNDODELETE:
+            case DBPROP_NOTIFYROWUNDOINSERT:
+            case DBPROP_NOTIFYROWUPDATE:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_I4(&propset[0].rgProperties[i].vValue) == 3, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            case DBPROP_BLOCKINGSTORAGEOBJECTS:
+            case DBPROP_IMMOBILEROWS:
+            case DBPROP_LITERALIDENTITY:
+            case DBPROP_REENTRANTEVENTS:
+            case DBPROP_IAccessor:
+            case DBPROP_IColumnsInfo:
+            case DBPROP_IColumnsRowset:
+            case DBPROP_IRowset:
+            case DBPROP_IRowsetInfo:
+            case DBPROP_ISupportErrorInfo:
+            case DBPROP_CHANGEINSERTEDROWS:
+            case DBPROP_IConvertType:
+            case DBPROP_IRowsetScroll:
+            case DBPROP_IRowsetRefresh:
+            case DBPROP_ORDEREDBOOKMARKS:
+            case DBPROP_CLIENTCURSOR:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_BOOL, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_BOOL(&propset[0].rgProperties[i].vValue) == VARIANT_TRUE, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+            default:
+                ok(V_VT(&propset[0].rgProperties[i].vValue) == VT_BOOL, "%d: got %d\n", i, V_VT(&propset[0].rgProperties[i].vValue));
+                ok(V_BOOL(&propset[0].rgProperties[i].vValue) == VARIANT_FALSE, "%d: got %d\n", i, V_I4(&propset[0].rgProperties[i].vValue));
+                break;
+        }
+    }
+
+    ok(IsEqualGUID(&DBPROPSET_PROVIDERROWSET, &propset[1].guidPropertySet), "got %s\n",
+        debugstr_guid(&propset[1].guidPropertySet));
+    for (i = 0; i < propset[1].cProperties; i++)
+    {
+        ok(propset[1].rgProperties[i].dwPropertyID == prov_props[i], "%d: got 0x%08x\n", i, propset[1].rgProperties[i].dwPropertyID);
+
+        switch(propset[1].rgProperties[i].dwPropertyID )
+        {
+            case DBPROP_AUTH_ENCRYPT_PASSWORD:
+                ok(V_VT(&propset[1].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[1].rgProperties[i].vValue));
+                ok(V_I4(&propset[1].rgProperties[i].vValue) == 0, "%d: got %d\n", i, V_I4(&propset[1].rgProperties[i].vValue));
+                break;
+            case DBPROP_AUTH_INTEGRATED:
+                ok(V_VT(&propset[1].rgProperties[i].vValue) == VT_I4, "%d: got %d\n", i, V_VT(&propset[1].rgProperties[i].vValue));
+                ok(V_I4(&propset[1].rgProperties[i].vValue) == 14, "%d: got %d\n", i, V_I4(&propset[1].rgProperties[i].vValue));
+                break;
+            case DBPROP_BLOCKINGSTORAGEOBJECTS:
+                ok(V_VT(&propset[1].rgProperties[i].vValue) == VT_BOOL, "%d: got %d\n", i, V_VT(&propset[1].rgProperties[i].vValue));
+                ok(V_BOOL(&propset[1].rgProperties[i].vValue) == VARIANT_FALSE, "%d: got %d\n", i, V_I4(&propset[1].rgProperties[i].vValue));
+                break;
+            default:
+                ok(V_VT(&propset[1].rgProperties[i].vValue) == VT_BOOL, "%d: got %d\n", i, V_VT(&propset[1].rgProperties[i].vValue));
+                ok(V_BOOL(&propset[1].rgProperties[i].vValue) == VARIANT_FALSE, "%d: got %d\n", i, V_I4(&propset[1].rgProperties[i].vValue));
+                break;
+        }
+    }
+
+    CoTaskMemFree(propset);
+}
+
 static void test_command_interfaces(IUnknown *cmd)
 {
     HRESULT hr;
@@ -198,6 +342,7 @@ static void test_command_interfaces(IUnknown *cmd)
 
     hr = IUnknown_QueryInterface(cmd, &IID_ICommandProperties, (void**)&commandProp);
     ok(hr == S_OK, "got 0x%08x\n", hr);
+    test_command_properties(commandProp);
     ICommandProperties_Release(commandProp);
 
     hr = IUnknown_QueryInterface(cmd, &IID_ICommandWithParameters, (void**)&cmdwithparams);
-- 
2.33.0




More information about the wine-devel mailing list