oledb32: Put provider initialization properties in a single DBPROP_INIT_PROVIDERSTRING.

Put provider initialization properties in a single DBPROP_INIT_PROVIDERSTRING for IDBProperties::SetProperties().
Otherwise, according to MSDN for IDBProperties::SetProperties(), if the same property is specified
more than once, the value used is provider-specific. So it won't be consider as an initialization property.

Fix PowerPivot for Excel not connecting to embedded data sources.
This commit is contained in:
Zhiyi Zhang 2023-05-08 22:15:10 +08:00 committed by Alexandre Julliard
parent 4085cca750
commit 3d514933b9
2 changed files with 33 additions and 18 deletions

View file

@ -518,6 +518,7 @@ static const struct dbproperty *get_known_dprop_descr(BSTR name)
static HRESULT get_dbpropset_from_proplist(struct dbprops *props, DBPROPSET **propset)
{
BSTR provider_string = NULL;
struct dbprop_pair *pair;
int i = 0;
HRESULT hr;
@ -535,6 +536,7 @@ static HRESULT get_dbpropset_from_proplist(struct dbprops *props, DBPROPSET **pr
}
(*propset)->cProperties = 0;
(*propset)->guidPropertySet = DBPROPSET_DBINIT;
LIST_FOR_EACH_ENTRY(pair, &props->props, struct dbprop_pair, entry)
{
const struct dbproperty *descr = get_known_dprop_descr(pair->name);
@ -542,25 +544,26 @@ static HRESULT get_dbpropset_from_proplist(struct dbprops *props, DBPROPSET **pr
if (!descr)
{
BSTR str;
int len;
/* provider specific property is always VT_BSTR */
len = SysStringLen(pair->name) + SysStringLen(pair->value) + 1 /* for '=' */;
str = SysAllocStringLen(NULL, len);
lstrcpyW(str, pair->name);
lstrcatW(str, L"=");
lstrcatW(str, pair->value);
len = SysStringLen(pair->name) + SysStringLen(pair->value) + 1; /* for '=' */
if (!provider_string)
{
provider_string = SysAllocStringLen(NULL, len);
}
else
{
BSTR old_string = provider_string;
(*propset)->cProperties++;
(*propset)->guidPropertySet = DBPROPSET_DBINIT;
(*propset)->rgProperties[i].dwPropertyID = DBPROP_INIT_PROVIDERSTRING;
(*propset)->rgProperties[i].dwOptions = DBPROPOPTIONS_REQUIRED;
(*propset)->rgProperties[i].dwStatus = 0;
memset(&(*propset)->rgProperties[i].colid, 0, sizeof(DBID));
V_VT(&(*propset)->rgProperties[i].vValue) = VT_BSTR;
V_BSTR(&(*propset)->rgProperties[i].vValue) = str;
i++;
len += SysStringLen(provider_string) + 1; /* for ';' separator */
provider_string = SysAllocStringLen(NULL, len);
lstrcpyW(provider_string, old_string);
lstrcatW(provider_string, L";");
SysFreeString(old_string);
}
lstrcatW(provider_string, pair->name);
lstrcatW(provider_string, L"=");
lstrcatW(provider_string, pair->value);
continue;
}
@ -581,7 +584,6 @@ static HRESULT get_dbpropset_from_proplist(struct dbprops *props, DBPROPSET **pr
}
(*propset)->cProperties++;
(*propset)->guidPropertySet = DBPROPSET_DBINIT;
(*propset)->rgProperties[i].dwPropertyID = descr->id;
(*propset)->rgProperties[i].dwOptions = descr->options;
(*propset)->rgProperties[i].dwStatus = 0;
@ -590,6 +592,20 @@ static HRESULT get_dbpropset_from_proplist(struct dbprops *props, DBPROPSET **pr
i++;
}
/* Provider specific property is always VT_BSTR */
/* DBPROP_INIT_PROVIDERSTRING should be specified only once. Otherwise, it will be considered as
* provider-specific rather than an initialization property */
if (provider_string)
{
(*propset)->cProperties++;
(*propset)->rgProperties[i].dwPropertyID = DBPROP_INIT_PROVIDERSTRING;
(*propset)->rgProperties[i].dwOptions = DBPROPOPTIONS_REQUIRED;
(*propset)->rgProperties[i].dwStatus = 0;
memset(&(*propset)->rgProperties[i].colid, 0, sizeof(DBID));
V_VT(&(*propset)->rgProperties[i].vValue) = VT_BSTR;
V_BSTR(&(*propset)->rgProperties[i].vValue) = provider_string;
}
return S_OK;
}

View file

@ -150,7 +150,6 @@ static HRESULT WINAPI dbprops_SetProperties(IDBProperties *iface, ULONG set_coun
ok(set_count == 1, "got %lu\n", set_count);
ok(IsEqualIID(&propsets->guidPropertySet, &DBPROPSET_DBINIT), "set guid %s\n", wine_dbgstr_guid(&propsets->guidPropertySet));
todo_wine_if(!wcscmp(V_BSTR(&propsets->rgProperties[0].vValue), L"provider_prop_test"))
ok(propsets->cProperties == 2, "got propcount %lu\n", propsets->cProperties);
if (propsets->cProperties == 2) {