Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The IDBInitialize interface contains two methods: Initialize and Uninitialize. The following sections discuss the implementation of these methods in the sample provider.
Initializing the Data Source Object
Initialize enables consumers to explicitly initialize a data source object. Consumers must set properties on the data source object before attempting to initialize it; and consumers must supply a valid directory path to the data file in IDBProperties::SetProperties. If the directory path is invalid, the sample provider returns an E_FAIL error on initialization. The source code for IDBInitialize::Initialize follows; you can find the complete source code for IDBInitialize in DBInit.cpp.
// CImpIDBInitialize::Initialize ---------------------------------------------
//
// @mfunc Initializes the DataSource object.. For this provider it requires
// that a valid path is given to where the file will be located.
//
// @rdesc HRESULT
// @flag S_OK | Path exists
// @flag E_FAIL | Invalid path
// @flag E_INVALIDARG | Invalid Parameters passed in
// @flag DB_E_ALREADYINITIALIZED | Datasource Object already initialized
//
STDMETHODIMP CImpIDBInitialize::Initialize
(
)
{
ASSERT( m_pObj );
CHAR szDataSource[MAX_PATH + MAX_PATH + 1] = {0};
HRESULT hr;
ULONG cPropSets = 0;
DBPROPSET* rgPropSets = NULL;
WCHAR* pwszDataSource = NULL;
int nPrompt = DBPROMPT_NOPROMPT;
HWND hWnd = NULL;
IDBPromptInitialize* pIDBPromptInitialize = NULL;
IDBProperties* pIDBProperties = NULL;
if(m_pObj->m_fDSOInitialized)
return ResultFromScode( DB_E_ALREADYINITIALIZED );
//Setup Properties
const ULONG cProperties = 3;
DBPROPID rgProperties[cProperties] = { DBPROP_INIT_DATASOURCE, DBPROP_INIT_PROMPT, DBPROP_INIT_HWND };
const ULONG cPropertyIDSets = 1;
DBPROPIDSET rgPropertyIDSets[cPropertyIDSets];
rgPropertyIDSets[0].guidPropertySet = DBPROPSET_DBINIT;
rgPropertyIDSets[0].rgPropertyIDs = rgProperties;
rgPropertyIDSets[0].cPropertyIDs = cProperties;
//Get the property values
hr = m_pObj->m_pUtilProp->GetProperties(PROPSET_DSO, cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets );
if(SUCCEEDED(hr))
{
pwszDataSource = V_BSTR(&rgPropSets[0].rgProperties[0].vValue);
nPrompt = V_I2(&rgPropSets[0].rgProperties[1].vValue);
#ifdef _WIN64
hWnd = (HWND)V_I8(&rgPropSets[0].rgProperties[2].vValue);
#else
hWnd = (HWND)V_I4(&rgPropSets[0].rgProperties[2].vValue);
#endif
//Convert Directory to MBCS
ConvertToMBCS(pwszDataSource, szDataSource, sizeof(szDataSource));
}
// if caller didn't supply a directory path, ask the user
if ((nPrompt == DBPROMPT_PROMPT) ||
((nPrompt == DBPROMPT_COMPLETE || nPrompt == DBPROMPT_COMPLETEREQUIRED) && (!SetCurrentDirectory(szDataSource))) )
{
//Use our current DataSource as defaults for properties
TESTC(hr = QueryInterface(IID_IDBProperties, (void**)&pIDBProperties));
//Use the Data Links Dialog to prompt...
TESTC(hr = CoCreateInstance(CLSID_DataLinks, NULL, CLSCTX_ALL, IID_IDBPromptInitialize, (void**)&pIDBPromptInitialize));
TESTC(hr = pIDBPromptInitialize->PromptDataSource(NULL, hWnd, DBPROMPTOPTIONS_PROPERTYSHEET | DBPROMPTOPTIONS_DISABLE_PROVIDER_SELECTION, 0, NULL, NULL, IID_IDBProperties, (IUnknown**)&pIDBProperties));
//Free the Previous Properties
FreeProperties(&cPropSets, &rgPropSets);
pwszDataSource = NULL;
//Now Data Links has put the user choosen properties onto our data source, we just need to
//reobtain the property values...
hr = m_pObj->m_pUtilProp->GetProperties(PROPSET_DSO, cPropertyIDSets, rgPropertyIDSets, &cPropSets, &rgPropSets );
if(SUCCEEDED(hr))
{
pwszDataSource = V_BSTR(&rgPropSets[0].rgProperties[0].vValue);
nPrompt = V_I2(&rgPropSets[0].rgProperties[1].vValue);
#ifdef _WIN64
hWnd = (HWND)V_I8(&rgPropSets[0].rgProperties[2].vValue);
#else
hWnd = (HWND)V_I4(&rgPropSets[0].rgProperties[2].vValue);
#endif
//Convert Directory to MBCS
ConvertToMBCS(pwszDataSource, szDataSource, sizeof(szDataSource));
}
}
//NOTE: We don't require DBPROP_INIT_DATASOURCE. If the DataSource property is passed
//in then we will use that to represent the current directory. This will allow the user
//to only have to specify the filename in OpenRowset, and not the full path...
if(szDataSource[0])
{
// Get the current Directory
CHAR szCurrentDir[MAX_PATH];
GetCurrentDirectory( MAX_PATH, szCurrentDir );
//See if the directory passed is valid...
if(!SetCurrentDirectory( szDataSource ))
{
hr = DB_E_ERRORSOCCURRED;
goto CLEANUP;
}
// Restore to the original directory.
SetCurrentDirectory( szCurrentDir );
wcsncpy_s( m_pObj->m_wszPath, _countof(m_pObj->m_wszPath ), pwszDataSource, MAX_PATH);
}
else
{
m_pObj->m_wszPath[0] = wEOL;
}
//We are now initialized...
m_pObj->m_fDSOInitialized = TRUE;
hr = S_OK;
CLEANUP:
FreeProperties(&cPropSets, &rgPropSets);
SAFE_RELEASE(pIDBPromptInitialize);
SAFE_RELEASE(pIDBProperties);
return hr;
}
Uninitializing the Data Source Object
Uninitialize enables consumers to return the data source object to an uninitialized state. It is an error to call IDBInitialize::Uninitialize when there are open sessions or rowsets on the data source object. The source code for IDBInitialize::Uninitialize follows.
// CImpIDBInitialize::Uninitialize ---------------------------------------------
//
// @mfunc Returns the Data Source Object to an uninitialized state
//
// @rdesc HRESULT
// @flag S_OK | The method succeeded
// @flag DB_E_OBJECTOPEN | A DBSession object was already created
//
STDMETHODIMP CImpIDBInitialize::Uninitialize
(
void
)
{
assert( m_pObj );
if (!m_pObj->m_fDSOInitialized)
{
// data source object is not initialized; do nothing
return ResultFromScode( S_OK );
}
else
{
if (!m_pObj->m_fDBSessionCreated)
{
// DSO initialized, but no DBSession has been created.
// So, reset DSO to uninitialized state
m_pObj->m_fDSOInitialized = FALSE;
return ResultFromScode( S_OK );
}
else
{
// DBSession has already been created; trying to uninit
// the DSO now is an error
return ResultFromScode( DB_E_OBJECTOPEN );
}
}
}