SQLOLEDB supports persisted data source objects with the IPersistFile interface.
This example shows a function that persists data source initialization properties that define a server, database, and the use of the Windows NT Authentication Mode for connection. The server name and database name are received in the pLocation and pDatasource parameters of the function.
HRESULT SetAndSaveInitProps
(
IDBInitialize* pIDBInitialize,
WCHAR* pLocation,
WCHAR* pDatasource,
BOOL bUseWinNTAuth
)
{
const ULONG nProps = 3;
ULONG nSSProps;
ULONG nPropSets;
ULONG nProp;
IDBProperties* pIDBProperties = NULL;
IPersistFile* pIPersistFile = NULL;
DBPROP aInitProps[nProps];
DBPROP* aSSInitProps = NULL;
DBPROPSET* aInitPropSets = NULL;
HRESULT hr;
// Setup arrays based on whether the Windows NT
// Authentication Mode is used.
if (bUseWinNTAuth == FALSE)
{
nSSProps = 0;
nPropSets = 1;
}
else
{
nPropSets = 2;
nSSProps = 1;
aSSInitProps = new DBPROP[nSSProps];
}
aInitPropSets = new DBPROPSET[nPropSets];
// Initialize common property options.
for (nProp = 0; nProp < nProps; nProp++)
{
VariantInit(&aInitProps[nProp].vValue);
aInitProps[nProp].dwOptions = DBPROPOPTIONS_REQUIRED;
aInitProps[nProp].colid = DB_NULLID;
}
// Level of prompting for rest of the connection
// process.
aInitProps[0].dwPropertyID = DBPROP_INIT_PROMPT;
aInitProps[0].vValue.vt = VT_I2;
aInitProps[0].vValue.iVal = DBPROMPT_NOPROMPT;
// Server name.
aInitProps[1].dwPropertyID = DBPROP_INIT_LOCATION;
aInitProps[1].vValue.vt = VT_BSTR;
aInitProps[1].vValue.bstrVal = SysAllocString(pLocation);
// Database.
aInitProps[2].dwPropertyID = DBPROP_INIT_DATASOURCE;
aInitProps[2].vValue.vt = VT_BSTR;
aInitProps[2].vValue.bstrVal = SysAllocString(pDatasource);
if (bUseWinNTAuth == TRUE)
{
// Initialize SQL Server provider-specific properties.
for (nProp = 0; nProp < nSSProps; nProp++)
{
VariantInit(&aSSInitProps[nProp].vValue);
aSSInitProps[nProp].dwOptions = DBPROPOPTIONS_REQUIRED;
aSSInitProps[nProp].colid = DB_NULLID;
}
// Windows NT Authentication Mode.
aSSInitProps[0].dwPropertyID = SSPROP_AUTH_TRUSTEDCONNECTION;
aSSInitProps[0].vValue.vt = VT_BOOL;
aSSInitProps[0].vValue.boolVal = VARIANT_TRUE;
}
// Now that properties are set, construct the PropertySet array.
aInitPropSets[0].guidPropertySet = DBPROPSET_DBINIT;
aInitPropSets[0].cProperties = nProps;
aInitPropSets[0].rgProperties = aInitProps;
if (bUseWinNTAuth == TRUE)
{
aInitPropSets[1].guidPropertySet = DBPROPSET_SQLSERVERDBINIT;
aInitPropSets[1].cProperties = nSSProps;
aInitPropSets[1].rgProperties = aSSInitProps;
}
// Set initialization properties.
pIDBInitialize->QueryInterface(IID_IDBProperties,
(void**) &pIDBProperties);
hr = pIDBProperties->SetProperties(nPropSets, aInitPropSets);
if (FAILED(hr))
{
// Display error from failed SetProperties.
}
pIDBProperties->Release();
// Free references on OLE known strings.
for (nProp = 0; nProp < nProps; nProp++)
{
if (aInitProps[nProp].vValue.vt == VT_BSTR)
SysFreeString(aInitProps[nProp].vValue.bstrVal);
}
// Free dynamically allocated memory.
delete [] aInitPropSets;
delete [] aSSInitProps;
// On success, persist the data source.
if (SUCCEEDED(hr))
{
pIDBInitialize->QueryInterface(IID_IPersistFile,
(void**) &pIPersistFile);
hr = pIPersistFile->Save(OLESTR("MyDataSource"), FALSE);
if (FAILED(hr))
{
// Display errors from IPersistFile interface.
}
pIPersistFile->Release();
}
return (hr);
}
This example uses a persisted data source object with additional initialization properties that provide a SQL Server login ID and password.
HRESULT InitFromPersistedDS
(
IDBInitialize* pIDBInitialize,
WCHAR* pPersistedDSN,
WCHAR* pUID,
WCHAR* pPWD
)
{
const ULONG nProps = 3;
const ULONG nPropSets = 1;
ULONG nProp;
IDBProperties* pIDBProperties = NULL;
IPersistFile* pIPersistFile = NULL;
DBPROP aInitProps[nProps];
DBPROPSET aInitPropSets[nPropSets];
HRESULT hr;
// First load the persisted data source information.
pIDBInitialize->QueryInterface(IID_IPersistFile,
(void**) &pIPersistFile);
hr = pIPersistFile->Load(pPersistedDSN, STGM_DIRECT);
if (FAILED(hr))
{
// Display errors from IPersistFile interface.
}
pIPersistFile->Release();
if (FAILED(hr))
{
return (hr);
}
// Initialize common property options.
for (nProp = 0; nProp < nProps; nProp++)
{
VariantInit(&aInitProps[nProp].vValue);
aInitProps[nProp].dwOptions = DBPROPOPTIONS_REQUIRED;
aInitProps[nProp].colid = DB_NULLID;
}
// Level of prompting for rest of the connection
// process.
aInitProps[0].dwPropertyID = DBPROP_INIT_PROMPT;
aInitProps[0].vValue.vt = VT_I2;
aInitProps[0].vValue.iVal = DBPROMPT_NOPROMPT;
// SQL Server login identifier.
aInitProps[1].dwPropertyID = DBPROP_AUTH_USERID;
aInitProps[1].vValue.vt = VT_BSTR;
aInitProps[1].vValue.bstrVal = SysAllocString(
(pUID != NULL ? pUID : OLESTR(““)));
// SQL Server password.
aInitProps[2].dwPropertyID = DBPROP_AUTH_PASSWORD;
aInitProps[2].vValue.vt = VT_BSTR;
aInitProps[2].vValue.bstrVal = SysAllocString(
(pPWD != NULL ? pPWD : OLESTR(““)));
// Now that properties are set, construct the PropertySet array.
aInitPropSets[0].guidPropertySet = DBPROPSET_DBINIT;
aInitPropSets[0].cProperties = nProps;
aInitPropSets[0].rgProperties = aInitProps;
// Set initialization properties.
pIDBInitialize->QueryInterface(IID_IDBProperties,
(void**) &pIDBProperties);
hr = pIDBProperties->SetProperties(nPropSets, aInitPropSets);
if (FAILED(hr))
{
// Display error from failed SetProperties.
}
pIDBProperties->Release();
// Free references on OLE-known strings.
for (nProp = 0; nProp < nProps; nProp++)
{
if (aInitProps[nProp].vValue.vt == VT_BSTR)
SysFreeString(aInitProps[nProp].vValue.bstrVal);
}
if (FAILED(hr))
{
return (hr);
}
hr = pIDBInitialize->Initialize();
return (hr);
}
The IPersistFile::Save function can be called before or after calling IDBInitialize::Initialize. Calling the function after a successful return from IDBInitialize::Initialize ensures persisting a valid data source specification.