// Binder.cpp : Implementation of CBinder #include "oleds.hxx" #if (!defined(BUILD_FOR_NT40)) #include "atl.h" #include "binder.hxx" #include "row.hxx" //property description constants const PWSTR DESC_DBPROP_INIT_LCID = L"Location ID"; const PWSTR DESC_DBPROP_INIT_MODE = L"Mode"; const PWSTR DESC_DBPROP_INIT_BINDFLAGS = L"Bind Flags"; const PWSTR DESC_DBPROP_INIT_LOCKOWNER = L"Lock Owner"; const PWSTR DESC_DBPROP_USERID = L"User ID"; const PWSTR DESC_DBPROP_PASSWORD = L"Password"; const PWSTR DESC_DBPROP_ENCRYPT_PASSWORD = L"Encrypt Password"; #define DEFAULT_DBPROP_INIT_MODE DB_MODE_READ ///////////////////////////////////////////////////////////////////////////// // CBinder //ISupportErrorInfo methods //+--------------------------------------------------------------------------- // // Function: CBinder::InterfaceSupportsErrorInfo // // Synopsis: Given an interface ID, tells if that interface supports // the interface ISupportErrorInfo // // Arguments: // REFIID riid // // Returns: // S_OK yes, the interface supports ISupportErrorInfo // S_FALSE no, the interface doesn't support it. //---------------------------------------------------------------------------- STDMETHODIMP CBinder::InterfaceSupportsErrorInfo(REFIID riid) { static const IID* arr[] = { &IID_IBindResource, &IID_IDBBinderProperties }; for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++) { if (InlineIsEqualGUID(*arr[i],riid)) RRETURN(S_OK); } RRETURN(S_FALSE); } //IBindResource methods //+--------------------------------------------------------------------------- // // Function: CBinder::Bind // // Synopsis: Binds to a row or rowset object given a URL. // // For more info see OLE DB 2.5 spec. //---------------------------------------------------------------------------- STDMETHODIMP CBinder::Bind( IUnknown * punkOuter, LPCOLESTR pwszURL, DBBINDURLFLAG dwBindFlags, REFGUID rguid, REFIID riid, IAuthenticate * pAuthenticate, DBIMPLICITSESSION * pImplSession, DWORD * pdwBindStatus, IUnknown ** ppUnk ) { HRESULT hr = S_OK; TRYBLOCK //if caller passed a null value for dwBindFlags, //get them from initialization properties. if (dwBindFlags == 0) dwBindFlags = BindFlagsFromDbProps(); //Forward the Bind call to CSessionObject for actual binding ADsAssert(m_pSession); hr = m_pSession->Bind(punkOuter, pwszURL, dwBindFlags, rguid, riid, pAuthenticate, pImplSession, pdwBindStatus, ppUnk); if (FAILED(hr)) RRETURN(hr); CATCHBLOCKRETURN RRETURN(hr); } //IDBBinderProperties : IDBProperties //(most of this code has been copied form exoledb and reorganized). //IDBProperties //+--------------------------------------------------------------------------- // // Function: CBinder::GetProperties // // Synopsis: Gets the requested Binder properties // // For more info see OLE DB 2.1 spec. //---------------------------------------------------------------------------- STDMETHODIMP CBinder::GetProperties( ULONG cPropertySets, const DBPROPIDSET rgPropertySets[ ], ULONG *pcPropertySets, DBPROPSET **prgPropertySets) { BOOL fPropInError, fSpecialSets, fCopy = FALSE; HRESULT hr = S_OK; LONG ipropset =0, iprop =0; ULONG cprop = 0, cpropError =0, ipropT; DBPROPSET *rgPropertySetsOutput = NULL, *ppropset = NULL; DBPROP *pprop; auto_leave cs_auto_leave(m_autocs); TRYBLOCK //Let property manager object check and init the arguments hr = m_dbProperties.CheckAndInitPropArgs(cPropertySets, rgPropertySets, pcPropertySets, (void **)prgPropertySets, &fPropInError, &fSpecialSets); //if all the requested sets are special, //we just return error because this method //doesn't support special sets. Otherwise, //we attempt to return information about other //non-special sets. if(fSpecialSets && SUCCEEDED(hr)) RRETURN(DB_E_ERRORSOCCURRED); else if(!fSpecialSets && FAILED(hr)) RRETURN(hr); cs_auto_leave.EnterCriticalSection(); //if cPropertySets is zero, return INIT property set. if(cPropertySets == 0) { cPropertySets = 1; fCopy = TRUE; } //or if DBPROPSET_PROPERTIESINERROR is requested, //check for invalid status values else if(fPropInError) { ppropset = m_dbProperties.GetPropertySet(DBPROPSET_DBINIT); for(iprop = 0, cpropError = 0; (ULONG)iprop < ppropset->cProperties; iprop++) if( ppropset->rgProperties[iprop].dwStatus != DBPROPSTATUS_OK ) cpropError++; } //Allocate memory for returning property sets. rgPropertySetsOutput = (DBPROPSET *)CoTaskMemAlloc(cPropertySets *sizeof(DBPROPSET)); if (!rgPropertySetsOutput) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); //If properties in error were requested, look for all properties //with invalid status values and return the info. if(fPropInError) { if(cpropError) { rgPropertySetsOutput[0].rgProperties =(DBPROP *)CoTaskMemAlloc(cpropError *sizeof(DBPROP)); if(rgPropertySetsOutput[0].rgProperties == NULL) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); } rgPropertySetsOutput[0].guidPropertySet = DBPROPSET_DBINIT; for(ipropT =0, iprop =0; ipropT cProperties; ipropT++) if( ppropset->rgProperties[ipropT].dwStatus != DBPROPSTATUS_OK ) { memcpy(&(rgPropertySetsOutput[0].rgProperties[iprop]), &(ppropset->rgProperties[ipropT]), sizeof(DBPROP)); VariantInit( &(rgPropertySetsOutput[0].rgProperties[iprop].vValue)); hr = VariantCopy( &(rgPropertySetsOutput[0].rgProperties[iprop].vValue), &(ppropset->rgProperties[ipropT].vValue)); BAIL_ON_FAILURE(hr); iprop++; } } else rgPropertySetsOutput[0].rgProperties = NULL; rgPropertySetsOutput[0].cProperties = cpropError; cpropError =0; } //if fCopy is set, copy the init property set to the return array else if(fCopy) { for (ipropset=0; (ULONG)ipropsetvValue)); BAIL_ON_FAILURE(hr); } //If unable to get property, set dwStatus else { cpropError++; rgPropertySetsOutput[ipropset]. rgProperties[iprop].dwPropertyID = rgPropertySets[ipropset].rgPropertyIDs[iprop]; rgPropertySetsOutput[ipropset]. rgProperties[iprop].dwStatus = DBPROPSTATUS_NOTSUPPORTED; } } } else //no propertyIDs requested for this set { rgPropertySetsOutput[ipropset].rgProperties = NULL; //DBPROPSET_DATASOURCEINFO is invalid for this object. //Return error if it is the one requested. if(ppropset == NULL || (rgPropertySets[ipropset].guidPropertySet == DBPROPSET_DATASOURCEINFO) ) { cprop++; cpropError++; } else //otherwise, copy all propertyIDs { hr = m_dbProperties.CopyPropertySet( rgPropertySets[ipropset].guidPropertySet, &rgPropertySetsOutput[ipropset]); BAIL_ON_FAILURE(hr); } } } //for (ipropset = 0.... } CATCHBLOCKBAIL(hr) ADsAssert(pcPropertySets && prgPropertySets); *pcPropertySets = cPropertySets; *prgPropertySets = rgPropertySetsOutput; hr = cpropError ? ((cpropError < cprop) ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED) : S_OK; RRETURN(hr); error: while(ipropset >= 0) { while(--iprop >= 0) VariantClear( &(rgPropertySetsOutput[ipropset].rgProperties[iprop].vValue)); if( rgPropertySetsOutput && rgPropertySetsOutput[ipropset].cProperties && rgPropertySetsOutput[ipropset].rgProperties) CoTaskMemFree(rgPropertySetsOutput[ipropset].rgProperties); ipropset--; } if(rgPropertySetsOutput) CoTaskMemFree(rgPropertySetsOutput); RRETURN(hr); } //+--------------------------------------------------------------------------- // // Function: CBinder::GetPropertyInfo // // Synopsis: Gets information about requested properties // // For more info see OLE DB 2.1 spec. //---------------------------------------------------------------------------- STDMETHODIMP CBinder::GetPropertyInfo( ULONG cPropertySets, const DBPROPIDSET rgPropertySets[ ], ULONG *pcPropertyInfoSets, DBPROPINFOSET **prgPropertyInfoSets, OLECHAR **ppDescBuffer) { HRESULT hr; BOOL fPropInError, fSpecialSets, fCopy =FALSE; ULONG ipropset = 0, iprop, cProperty, cprop = 0, cpropError=0; ULONG_PTR cchDescBuffer, ichDescBuffer; DBPROPINFOSET *rgPropertyInfoSetsOutput = NULL, *ppropinfoset; const DBPROPINFO UNALIGNED *pdbpropinfoSrc; PDBPROPINFO pdbpropinfo; auto_leave cs_auto_leave(m_autocs); TRYBLOCK if(ppDescBuffer) { *ppDescBuffer = NULL; cchDescBuffer = 0; ichDescBuffer = 0; } //Let the property manager object check and init arguments hr = m_dbProperties.CheckAndInitPropArgs(cPropertySets, rgPropertySets, pcPropertyInfoSets, (void **)prgPropertyInfoSets, &fPropInError, &fSpecialSets); if(FAILED(hr)) RRETURN(hr); else if(fPropInError) RRETURN(E_INVALIDARG); cs_auto_leave.EnterCriticalSection(); //if cPropertySets is zero, return INIT property set info if(cPropertySets == 0) { cPropertySets = 1; fCopy = TRUE; } rgPropertyInfoSetsOutput = (DBPROPINFOSET *) CoTaskMemAlloc(cPropertySets*sizeof(DBPROPINFOSET)); if (!rgPropertyInfoSetsOutput) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); if(fCopy) { for (ipropset=0; ipropset dwPropertyID = rgPropertySets[ipropset]. rgPropertyIDs[iprop]; pdbpropinfo->dwFlags = DBPROPFLAGS_NOTSUPPORTED; cpropError++; } } //Now copy property descriptions //for all properties in this set hr = m_dbProperties.CopyPropertyDescriptions( &rgPropertyInfoSetsOutput[ipropset], ppDescBuffer, &cchDescBuffer, &ichDescBuffer); BAIL_ON_FAILURE(hr); } } else //no properties stored in this set. { cprop++; //if the returned set itself is NULL, nothing //to copy. if(ppropinfoset == NULL) { cpropError++; rgPropertyInfoSetsOutput[ipropset].rgPropertyInfos = NULL; } //otherwise, just copy whatever info we have //in the set. else { hr = m_dbProperties.CopyPropertyInfoSet( rgPropertySets[ipropset].guidPropertySet, &rgPropertyInfoSetsOutput[ipropset], ppDescBuffer, &cchDescBuffer, &ichDescBuffer); BAIL_ON_FAILURE(hr); } } } } //for (ipropset = 0 .... } //if (fcopy) ... else ... CATCHBLOCKBAIL(hr) *pcPropertyInfoSets = cPropertySets; *prgPropertyInfoSets = rgPropertyInfoSetsOutput; // So far we have put relative offsets into pointers to property // descriptions. They have to be rebased on the beginning of the // desription strings buffer. if(ppDescBuffer && *ppDescBuffer) { for(ipropset=0; ipropset < cPropertySets; ipropset++) for(iprop =0; iprop dwPropertyID); //if property is already there.... if(ppropStored) { ppropNew->dwStatus = DBPROPSTATUS_OK; //Set error status if validation fails or //if type doesn't match //or if bad option or fEqualOnly is set //but new and existing values aren't the same. if (ppropNew->dwPropertyID == DBPROP_INIT_MODE && (V_VT(&(ppropNew->vValue)) == VT_I4) && V_I4(&ppropNew->vValue) != DB_MODE_READ) ppropNew->dwStatus = DBPROPSTATUS_BADVALUE; else if(V_VT(&(ppropNew->vValue)) != (m_dbProperties.GetPropertyInfo( rgPropertySets[ipropset].guidPropertySet, ppropNew->dwPropertyID))->vtType) { if(V_VT(&(ppropNew->vValue)) != VT_EMPTY) ppropNew->dwStatus = DBPROPSTATUS_BADVALUE; else if(fEqualOnly) ppropNew->dwStatus = DBPROPSTATUS_NOTSETTABLE; } else if(!GoodPropOption(ppropNew->dwOptions)) ppropNew->dwStatus = DBPROPSTATUS_BADOPTION; else if(fEqualOnly && !VariantsEqual( &(ppropNew->vValue), &(ppropStored->vValue))) ppropNew->dwStatus = DBPROPSTATUS_NOTSETTABLE; //fEqualOnly was not set if(!fEqualOnly && ppropNew->dwStatus == DBPROPSTATUS_OK) { // If VT_EMPTY we need to reset the default. if(V_VT(&(ppropNew->vValue)) == VT_EMPTY) { // Reset our initialization properties // to the default: if(ppropNew->dwPropertyID == DBPROP_INIT_LCID) { V_VT(&(ppropNew->vValue)) = VT_I4; V_I4(&(ppropNew->vValue)) = GetUserDefaultLCID(); } else if ( ppropNew->dwPropertyID == DBPROP_INIT_MODE) { V_VT(&(ppropNew->vValue)) = VT_I4; V_I4(&(ppropNew->vValue)) = DEFAULT_DBPROP_INIT_MODE; } else if ( ppropNew->dwPropertyID == DBPROP_INIT_BINDFLAGS) { V_VT(&(ppropNew->vValue)) = VT_I4; V_I4(&(ppropNew->vValue)) = 0; } else if ( ppropNew->dwPropertyID == DBPROP_INIT_LOCKOWNER) { V_VT(&(ppropNew->vValue)) = VT_BSTR; V_BSTR(&(ppropNew->vValue)) = NULL; } else if ( ppropNew->dwPropertyID == DBPROP_AUTH_USERID) { V_VT(&(ppropNew->vValue)) = VT_BSTR; V_BSTR(&(ppropNew->vValue)) = NULL; } else if ( ppropNew->dwPropertyID == DBPROP_AUTH_PASSWORD) { V_VT(&(ppropNew->vValue)) = VT_BSTR; V_BSTR(&(ppropNew->vValue)) = NULL; } else if ( ppropNew->dwPropertyID == DBPROP_AUTH_ENCRYPT_PASSWORD) { V_VT(&(ppropNew->vValue)) = VT_BOOL; V_BOOL(&(ppropNew->vValue)) = VARIANT_FALSE; } fRestore = TRUE; } else fRestore = FALSE; //copy new value into the property variant. if(FAILED(VariantCopy( &(ppropStored->vValue), &(ppropNew->vValue)))) ppropNew->dwStatus = DBPROPSTATUS_NOTSET; else if( ppropNew->dwPropertyID == DBPROP_AUTH_USERID ) { if(S_OK != m_pSession->SetUserName(V_BSTR(&(ppropNew->vValue)))) ppropNew->dwStatus = DBPROPSTATUS_NOTSET; } else if( ppropNew->dwPropertyID == DBPROP_AUTH_PASSWORD ) { if(S_OK != m_pSession->SetPassword(V_BSTR(&(ppropNew->vValue)))) ppropNew->dwStatus = DBPROPSTATUS_NOTSET; } else if( ppropNew->dwPropertyID == DBPROP_AUTH_ENCRYPT_PASSWORD ) { if(V_BOOL(&(ppropNew->vValue)) == VARIANT_TRUE) m_pSession->SetAuthFlag(ADS_SECURE_AUTHENTICATION); } if(fRestore) VariantInit(&(ppropNew->vValue)); } } else ppropNew->dwStatus = DBPROPSTATUS_NOTSUPPORTED; if(ppropNew->dwStatus != DBPROPSTATUS_OK) cpropError++; } } else { cpropError += rgPropertySets[ipropset].cProperties; for(; ppropNew !=ppropEnd; ppropNew++) ppropNew->dwStatus = dbpropstat; } } //for (ipropset = 0 ... CATCHBLOCKRETURN hr = cpropError ? ((cpropError vValue ); V_VT(&pprop->vValue) = VT_I4; V_I4(&pprop->vValue) = GetUserDefaultLCID(); pprop = (DBPROP *) m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_INIT_MODE ); ADsAssert ( pprop ); VariantClear ( &pprop->vValue ); V_VT(&pprop->vValue) = VT_I4; V_I4(&pprop->vValue) = DEFAULT_DBPROP_INIT_MODE; pprop = (DBPROP *) m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_INIT_BINDFLAGS ); ADsAssert ( pprop ); VariantClear ( &pprop->vValue ); V_VT(&pprop->vValue) = VT_I4; V_I4(&pprop->vValue) = 0; pprop = (DBPROP *) m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_INIT_LOCKOWNER ); ADsAssert ( pprop ); VariantClear ( &pprop->vValue ); V_VT(&pprop->vValue) = VT_BSTR; V_BSTR(&pprop->vValue) = NULL; pprop = (DBPROP *) m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_AUTH_USERID ); ADsAssert ( pprop ); VariantClear ( &pprop->vValue ); V_VT(&pprop->vValue) = VT_BSTR; V_BSTR(&pprop->vValue) = NULL; m_pSession->SetUserName(NULL); pprop = (DBPROP *) m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_AUTH_PASSWORD ); ADsAssert ( pprop ); VariantClear ( &pprop->vValue ); V_VT(&pprop->vValue) = VT_BSTR; V_BSTR(&pprop->vValue) = NULL; m_pSession->SetPassword(NULL); pprop = (DBPROP *) m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_AUTH_ENCRYPT_PASSWORD ); ADsAssert ( pprop ); VariantClear ( &pprop->vValue ); V_VT(&pprop->vValue) = VT_BOOL; V_BOOL(&pprop->vValue) = VARIANT_FALSE; m_pSession->SetAuthFlag(0); CATCHBLOCKRETURN RRETURN(hr); } //Helper functions //+--------------------------------------------------------------------------- // // Function: CBinder::InitializeProperties // // Synopsis: Initializes binder init property group to default values. // //---------------------------------------------------------------------------- HRESULT CBinder::InitializeProperties() { HRESULT hr; DBPROP prop; DBPROPINFO * ppropinfo; // Initialize the DBPROP structure: // ZeroMemory ( &prop, sizeof (prop) ); prop.dwOptions = DBPROPOPTIONS_OPTIONAL; prop.dwStatus = DBPROPSTATUS_OK; // Add the LCID: // prop.dwPropertyID = DBPROP_INIT_LCID; V_VT(&prop.vValue) = VT_I4; V_I4(&prop.vValue) = GetUserDefaultLCID (); hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_INIT_LCID ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *)m_dbProperties.GetPropertyInfo( DBPROPSET_DBINIT, DBPROP_INIT_LCID); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; // Add the DB_MODE: // prop.dwPropertyID = DBPROP_INIT_MODE; V_VT(&prop.vValue) = VT_I4; V_I4(&prop.vValue) = DEFAULT_DBPROP_INIT_MODE; hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_INIT_MODE ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo ( DBPROPSET_DBINIT, DBPROP_INIT_MODE ); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; // Add the BindFlags property: // prop.dwPropertyID = DBPROP_INIT_BINDFLAGS; V_VT(&prop.vValue) = VT_I4; V_I4(&prop.vValue) = 0; hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_INIT_BINDFLAGS ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo ( DBPROPSET_DBINIT, DBPROP_INIT_BINDFLAGS ); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; // Add the LOCKOWNER property: // prop.dwPropertyID = DBPROP_INIT_LOCKOWNER; V_VT(&prop.vValue) = VT_BSTR; V_BSTR(&prop.vValue) = NULL; hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_INIT_LOCKOWNER ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo ( DBPROPSET_DBINIT, DBPROP_INIT_LOCKOWNER ); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; // Add the USERID property: // prop.dwPropertyID = DBPROP_AUTH_USERID; V_VT(&prop.vValue) = VT_BSTR; V_BSTR(&prop.vValue) = NULL; hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_USERID ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo ( DBPROPSET_DBINIT, DBPROP_AUTH_USERID ); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; // Add the PASSWORD property: // prop.dwPropertyID = DBPROP_AUTH_PASSWORD; V_VT(&prop.vValue) = VT_BSTR; V_BSTR(&prop.vValue) = NULL; hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_PASSWORD ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo ( DBPROPSET_DBINIT, DBPROP_AUTH_PASSWORD ); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; // Add the ENCRYPT_PASSWORD property: // prop.dwPropertyID = DBPROP_AUTH_ENCRYPT_PASSWORD; V_VT(&prop.vValue) = VT_BOOL; V_BOOL(&prop.vValue) = VARIANT_FALSE; hr = m_dbProperties.SetProperty ( DBPROPSET_DBINIT, prop, TRUE, DESC_DBPROP_ENCRYPT_PASSWORD ); BAIL_ON_FAILURE(hr); // Make it writable: ppropinfo = (DBPROPINFO *) m_dbProperties.GetPropertyInfo ( DBPROPSET_DBINIT, DBPROP_AUTH_ENCRYPT_PASSWORD ); ADsAssert ( ppropinfo ); ppropinfo->dwFlags |= DBPROPFLAGS_WRITE; error: RRETURN ( hr ); } //+--------------------------------------------------------------------------- // // Function: CBinder::BindFlagsFromDbProps // // Synopsis: extracts bind flags from initialization properties. // //---------------------------------------------------------------------------- DWORD CBinder::BindFlagsFromDbProps ( ) { const DBPROP * ppropMode; const DBPROP * ppropBindFlags; ppropMode = m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_INIT_MODE ); ADsAssert ( ppropMode ); ppropBindFlags = m_dbProperties.GetProperty ( DBPROPSET_DBINIT, DBPROP_INIT_BINDFLAGS ); ADsAssert ( ppropBindFlags ); const VARIANT * pvarMode = &ppropMode->vValue; const VARIANT * pvarBindFlags = &ppropBindFlags->vValue; DWORD dwResult = 0; if ( V_VT(pvarMode) == VT_I4 ) { DWORD dwModeMask = DB_MODE_READ | DB_MODE_WRITE | DB_MODE_READWRITE | DB_MODE_SHARE_DENY_READ | DB_MODE_SHARE_DENY_WRITE | DB_MODE_SHARE_EXCLUSIVE | DB_MODE_SHARE_DENY_NONE; dwResult |= V_I4(pvarMode) & dwModeMask; } if ( V_VT(pvarBindFlags) == VT_I4 ) { DWORD dwBindFlagProp = V_I4(pvarBindFlags); DWORD dwBindFlags = 0; if ( dwBindFlagProp & DB_BINDFLAGS_DELAYFETCHCOLUMNS ) { dwBindFlags |= DBBINDURLFLAG_DELAYFETCHCOLUMNS; } if ( dwBindFlagProp & DB_BINDFLAGS_DELAYFETCHSTREAM ) { dwBindFlags |= DBBINDURLFLAG_DELAYFETCHSTREAM; } if ( dwBindFlagProp & DB_BINDFLAGS_RECURSIVE ) { dwBindFlags |= DBBINDURLFLAG_RECURSIVE; } if ( dwBindFlagProp & DB_BINDFLAGS_OUTPUT ) { dwBindFlags |= DBBINDURLFLAG_OUTPUT; } dwResult |= V_I4(pvarBindFlags) | dwBindFlags; } RRETURN (dwResult); } //+--------------------------------------------------------------------------- // // Function: CBinder::CreateDataSource // // Synopsis: Creates an implicit DataSource object for this binder object. // //---------------------------------------------------------------------------- HRESULT CBinder::CreateDataSource() { //Call this function only at creation time. ADsAssert(m_pDataSource == NULL && m_pDBInitialize.get() == NULL); HRESULT hr = S_OK; //Create a DataSource object. Note: starts with refcount = 1. m_pDataSource = new CDSOObject( NULL ); if (m_pDataSource == NULL) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); //Initialize the object if (!m_pDataSource->FInit()) { delete m_pDataSource; m_pDataSource = NULL; BAIL_ON_FAILURE(hr = E_FAIL); } //Get IDBInitialize interface and store it in (auto)member variable. //This will also make sure the DataSource object stays alive during //the lifetime of binder object. hr = m_pDataSource->QueryInterface(__uuidof(IDBInitialize), (void**)&m_pDBInitialize); BAIL_ON_FAILURE(hr); //We already stored datasource object reference in auto_rel object, //Now release once, since datasource object is created with refcount = 1. m_pDataSource->Release(); error: RRETURN ( hr ); } //+--------------------------------------------------------------------------- // // Function: CBinder::CreateSession // // Synopsis: Creates an implicit Session object for this binder object. // //---------------------------------------------------------------------------- HRESULT CBinder::CreateSession() { //Call this function only at creation time. ADsAssert(m_pSession == NULL && m_pOpenRowset.get() == NULL); HRESULT hr = S_OK; CCredentials creds; //create a session object. Note: starts with refcount = 1 m_pSession = new CSessionObject( NULL ); if (m_pSession == NULL) BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); //Initialize session object passing null credentials. //Note: This increments refcount on DataSource object. if (!m_pSession->FInit(m_pDataSource, creds)) BAIL_ON_FAILURE(hr = E_FAIL); hr = m_pSession->QueryInterface(__uuidof(IOpenRowset), (void **)&m_pOpenRowset); BAIL_ON_FAILURE(hr); //We already stored session reference in auto_rel object. //Now release once, since session object is created //with refcount = 1 m_pSession->Release(); RRETURN ( S_OK ); error: //if we're here, the Session object is no good. if (m_pSession) { delete m_pSession; m_pSession = NULL; } RRETURN ( hr ); } #endif