diff --git a/dlls/msdasql/msdasql_main.c b/dlls/msdasql/msdasql_main.c index 60d46349590..017a2517a72 100644 --- a/dlls/msdasql/msdasql_main.c +++ b/dlls/msdasql/msdasql_main.c @@ -40,6 +40,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 199eb0830d6..795927fe778 100644 --- a/dlls/msdasql/session.c +++ b/dlls/msdasql/session.c @@ -36,6 +36,99 @@ 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 }, +}; + struct msdasql_session { IUnknown session_iface; @@ -332,6 +425,9 @@ struct command IUnknown *session; HDBC hdbc; SQLHSTMT hstmt; + + struct msdasql_prop *properties; + LONG prop_count; }; static inline struct command *impl_from_ICommandText( ICommandText *iface ) @@ -449,6 +545,8 @@ static ULONG WINAPI command_Release(ICommandText *iface) if (!refs) { TRACE( "destroying %p\n", command ); + if (command->properties) + heap_free(command->properties); if (command->session) IUnknown_Release(command->session); @@ -989,12 +1087,146 @@ static ULONG WINAPI command_prop_Release(ICommandProperties *iface) return ICommandText_Release(&command->ICommandText_iface); } +static ULONG get_property_count(DWORD flag, struct msdasql_prop *properties, int prop_count) +{ + int i, count = 0; + + for(i=0; i < prop_count; i++) + { + if (properties[i].flags & flag) + count++; + } + + return count; +} + static HRESULT WINAPI command_prop_GetProperties(ICommandProperties *iface, ULONG count, const DBPROPIDSET propertyidsets[], ULONG *sets_cnt, DBPROPSET **propertyset) { struct command *command = impl_from_ICommandProperties( iface ); - FIXME("%p %lu %p %p %p\n", command, count, propertyidsets, sets_cnt, propertyset); - return E_NOTIMPL; + DBPROPSET *propset = NULL; + int i, j, k; + + TRACE("%p %ld %p %p %p\n", command, count, propertyidsets, sets_cnt, propertyset); + + /* All Properties */ + if (count == 0) + { + int idx; + propset = CoTaskMemAlloc(2 * sizeof(DBPROPSET)); + if (!propset) + return E_OUTOFMEMORY; + + propset[0].guidPropertySet = DBPROPSET_ROWSET; + propset[0].cProperties = get_property_count(DBPROPFLAGS_ROWSET, command->properties, command->prop_count); + propset[0].rgProperties = CoTaskMemAlloc(propset[0].cProperties * sizeof(DBPROP)); + if (!propset[0].rgProperties) + { + CoTaskMemFree(propset); + return E_OUTOFMEMORY; + } + + idx = 0; + for (j=0; j < command->prop_count; j++) + { + if (!(command->properties[j].flags & DBPROPFLAGS_ROWSET)) + continue; + propset[0].rgProperties[idx].dwPropertyID = command->properties[j].property_id; + + V_VT(&propset[0].rgProperties[idx].vValue) = command->properties[j].vartype; + if (command->properties[j].vartype == VT_BOOL) + { + V_BOOL(&propset[0].rgProperties[idx].vValue) = command->properties[j].value; + } + else if (command->properties[j].vartype == VT_I4) + { + V_I4(&propset[0].rgProperties[idx].vValue) = command->properties[j].value; + } + else + ERR("Unknown variant type %d\n", command->properties[j].vartype); + + idx++; + } + + propset[1].guidPropertySet = DBPROPSET_PROVIDERROWSET; + propset[1].cProperties = get_property_count(DBPROPFLAGS_DATASOURCEINFO, command->properties, command->prop_count); + propset[1].rgProperties = CoTaskMemAlloc(propset[1].cProperties * sizeof(DBPROP)); + if (!propset[1].rgProperties) + { + CoTaskMemFree(propset[0].rgProperties); + CoTaskMemFree(propset); + return E_OUTOFMEMORY; + } + + idx = 0; + for (j=0; j < command->prop_count; j++) + { + if (!(command->properties[j].flags & DBPROPFLAGS_DATASOURCEINFO)) + continue; + propset[1].rgProperties[idx].dwPropertyID = command->properties[j].property_id; + + V_VT(&propset[1].rgProperties[idx].vValue) = command->properties[j].vartype; + if (command->properties[j].vartype == VT_BOOL) + { + V_BOOL(&propset[1].rgProperties[idx].vValue) = command->properties[j].value; + } + else if (command->properties[j].vartype == VT_I4) + { + V_I4(&propset[1].rgProperties[idx].vValue) = command->properties[j].value; + } + else + ERR("Unknown variant type %d\n", command->properties[j].vartype); + + idx++; + } + + *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 %ld, 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 < command->prop_count; 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, @@ -1227,6 +1459,10 @@ static HRESULT WINAPI createcommand_CreateCommand(IDBCreateCommand *iface, IUnkn command->hdbc = session->hdbc; command->hstmt = NULL; + command->prop_count = ARRAY_SIZE(msdasql_init_props); + command->properties = heap_alloc(sizeof(msdasql_init_props)); + 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 d261e34e987..00fa9194459 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%08lx\n", hr); + ok(count == 2, "got %ld\n", count); + ok(propset[0].cProperties == 68, "got %ld\n", propset[0].cProperties); + ok(propset[1].cProperties == 12, "got %ld\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%08lx\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 %ld\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 %ld\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 %ld\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 %ld\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 %ld\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 %ld\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 %ld\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 %ld\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%08lx\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 %ld\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 %ld\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 %ld\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 %ld\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%08lx\n", hr); + test_command_properties(commandProp); ICommandProperties_Release(commandProp); hr = IUnknown_QueryInterface(cmd, &IID_ICommandWithParameters, (void**)&cmdwithparams);