//--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995 // // File: cdso.cxx // // Contents: Microsoft OleDB/OleDS Data Source Object for ADSI // // // History: 08-01-96 shanksh Created. // //------------------------------------------------------------------------------ #include "oleds.hxx" #pragma hdrstop extern LONG glnOledbObjCnt; //+--------------------------------------------------------------------------- // // Function: CDSOObject::CreateDSOObject // // Synopsis: Creates a new DB Session object from the DSO, and returns the // requested interface on the newly created object. // // Arguments: pUnkOuter Controlling IUnknown if being aggregated // riid The ID of the interface // ppDBSession A pointer to memory in which to return the // interface pointer // // Returns: // S_OK The method succeeded. // E_INVALIDARG ppDBSession was NULL // DB_E_NOAGGREGATION pUnkOuter was not NULL (this object // does not support being aggregated) // E_FAIL Provider-specific error. This // E_OUTOFMEMORY Out of memory // E_NOINTERFACE Could not obtain requested interface on // DBSession object // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- HRESULT CDSOObject::CreateDSOObject( IUnknown * pUnkOuter, REFIID riid, void ** ppvObj ) { CDSOObject* pDSO = NULL; HRESULT hr; // // check in-params and NULL out-params in case of error // if( ppvObj ) *ppvObj = NULL; else RRETURN( E_INVALIDARG ); if( pUnkOuter )// && !InlineIsEqualGUID(riid, IID_IUnknown) ) RRETURN( DB_E_NOAGGREGATION ); // // open a DBSession object // pDSO = new CDSOObject(pUnkOuter); if( !pDSO ) RRETURN( E_OUTOFMEMORY ); // // initialize the object // if( !pDSO->FInit() ) { delete pDSO; RRETURN( E_OUTOFMEMORY ); } // // get requested interface pointer on DSO Object // hr = pDSO->QueryInterface( riid, (void **)ppvObj); if( FAILED( hr ) ) { delete pDSO; RRETURN( hr ); } pDSO->Release(); RRETURN( S_OK ); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::Initialize // // Synopsis: Initializes the DataSource object. // // Arguments: // // // Returns: HRESULT // S_OK // E_FAIL // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::Initialize( void ) { HRESULT hr = S_OK; if( _fDSOInitialized ) RRETURN( DB_E_ALREADYINITIALIZED); if(IsIntegratedSecurity()) { // // If using integrated security, we need to save the calling thread's // security context here. Reason is that when we actually connect to // the directory, we could be running on a different context, and we // need to impersonate this context to work correctly. // if (!OpenThreadToken( GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &_ThreadToken)) { // // If thread doesn't have a token, use process token // if (GetLastError() != ERROR_NO_TOKEN || !OpenProcessToken( GetCurrentProcess(), TOKEN_ALL_ACCESS, &_ThreadToken)) { GetLastError(); BAIL_ON_FAILURE(hr = E_FAIL); } } } _fDSOInitialized = TRUE; error: RRETURN (hr); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::Uninitialize // // Synopsis: Returns the Data Source Object to an uninitialized state // // Arguments: // // // Returns: HRESULT // S_OK | The method succeeded // DB_E_OBJECTOPEN | A DBSession object was already created // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::Uninitialize( void ) { // // data source object is not initialized; do nothing // if( !_fDSOInitialized ) { RRETURN( S_OK ); } else { if( !IsSessionOpen() ) { // // DSO initialized, but no DBSession is open. // So, reset DSO to uninitialized state // if (_ThreadToken) { CloseHandle(_ThreadToken); _ThreadToken = NULL; } _fDSOInitialized = FALSE; RRETURN( S_OK ); } else { // // DBSession has already been created; trying to uninit // the DSO now is an error // RRETURN( DB_E_OBJECTOPEN ); } } } //+--------------------------------------------------------------------------- // // Function: CDSOObject::GetProperties // // Synopsis: Returns current settings of all properties in the // DBPROPFLAGS_DATASOURCE property group // // Arguments: // cPropertySets count of restiction guids // rgPropertySets restriction guids // pcProperties count of properties returned // pprgProperties property information returned // // Returns: HRESULT // S_OK | The method succeeded // E_FAIL | Provider specific error // E_INVALIDARG | pcPropertyInfo or prgPropertyInfo was NULL // E_OUTOFMEMORY | Out of memory // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::GetProperties( ULONG cPropIDSets, const DBPROPIDSET rgPropIDSets[], ULONG * pcPropSets, DBPROPSET ** pprgPropSets ) { // // Asserts // ADsAssert(_pUtilProp); // // If the Data Source object is initialized. // DWORD dwBitMask = PROPSET_DSO; if( _fDSOInitialized ) dwBitMask |= PROPSET_INIT; // // Validate the GetProperties Arguments // HRESULT hr = _pUtilProp->GetPropertiesArgChk( cPropIDSets, rgPropIDSets, pcPropSets, pprgPropSets, dwBitMask); if( FAILED(hr) ) RRETURN( hr ); // // Just pass this call on to the utility object that manages our properties // RRETURN( _pUtilProp->GetProperties( cPropIDSets, rgPropIDSets, pcPropSets, pprgPropSets, dwBitMask ) ); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::GetPropertyInfo // // Synopsis: Returns information about rowset and data source properties supported // by the provider // // Arguments: // cPropertySets Number of properties being asked about // rgPropertySets Array of cPropertySets properties about // which to return information // pcPropertyInfoSets Number of properties for which information // is being returned // prgPropertyInfoSets Buffer containing default values returned // ppDescBuffer Buffer containing property descriptions // // Returns: HRESULT // S_OK | The method succeeded // E_FAIL | Provider specific error // E_INVALIDARG | pcPropertyInfo or prgPropertyInfo was NULL // E_OUTOFMEMORY | Out of memory // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::GetPropertyInfo( ULONG cPropertyIDSets, const DBPROPIDSET rgPropertyIDSets[], ULONG * pcPropertyInfoSets, DBPROPINFOSET ** pprgPropertyInfoSets, WCHAR ** ppDescBuffer) { // // Asserts // ADsAssert(_pUtilProp); // // Just pass this call on to the utility object that manages our properties // RRETURN( _pUtilProp->GetPropertyInfo( cPropertyIDSets, rgPropertyIDSets, pcPropertyInfoSets, pprgPropertyInfoSets, ppDescBuffer, _fDSOInitialized) ); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::SetProperties // // Synopsis: Set properties in the DBPROPFLAGS_DATASOURCE property group // // Arguments: // cPropertySets // rgPropertySets // // Returns: HRESULT // E_INVALIDARG | cProperties was not equal to 0 and // rgProperties was NULL // E_FAIL | Provider specific error // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::SetProperties( ULONG cPropertySets, DBPROPSET rgPropertySets[] ) { // // Asserts // ADsAssert(_pUtilProp); // // If the Data Source object is initialized. // DWORD dwBitMask = PROPSET_DSO; if( _fDSOInitialized ) dwBitMask |= PROPSET_INIT; // // Just pass this call on to the utility object that manages our properties // RRETURN( _pUtilProp->SetProperties( cPropertySets, rgPropertySets, dwBitMask) ); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::GetClassID // // Synopsis: // // Arguments: // // // // Returns: // // // // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::GetClassID( CLSID * pClassID ) { if( pClassID ) { memcpy(pClassID, &CLSID_ADsDSOObject, sizeof(CLSID)); RRETURN( S_OK ); } RRETURN( E_FAIL ); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::CreateSession // // Synopsis: Creates a new DB Session object from the DSO, and returns the // requested interface on the newly created object. // // Arguments: // pUnkOuter, Controlling IUnknown if being aggregated // riid, The ID of the interface // ppDBSession A pointer to memory in which to return the // interface pointer // // Returns: HRESULT // S_OK The method succeeded. // E_INVALIDARG ppDBSession was NULL // DB_E_NOAGGREGATION pUnkOuter was not NULL (this object // does not support being aggregated) // E_FAIL Provider-specific error. This // provider can only create one DBSession // E_OUTOFMEMORY Out of memory // E_NOINTERFACE Could not obtain requested interface // on DBSession object // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::CreateSession( IUnknown * pUnkOuter, REFIID riid, IUnknown ** ppDBSession ) { CSessionObject* pDBSession = NULL; HRESULT hr; BOOL fSuccess; // // check in-params and NULL out-params in case of error // if( ppDBSession ) *ppDBSession = NULL; else RRETURN( E_INVALIDARG ); if( pUnkOuter )//&& !InlineIsEqualGUID(riid, IID_IUnknown) ) RRETURN( DB_E_NOAGGREGATION ); if( !_fDSOInitialized ) { RRETURN(E_UNEXPECTED); } // // open a DBSession object // pDBSession = new CSessionObject(pUnkOuter); if( !pDBSession ) RRETURN( E_OUTOFMEMORY ); // // initialize the object // if( _pUtilProp->IsIntegratedSecurity() ) { CCredentials tempCreds; tempCreds.SetUserName(NULL); tempCreds.SetPassword(NULL); tempCreds.SetAuthFlags(_Credentials.GetAuthFlags()); fSuccess = pDBSession->FInit(this, tempCreds); } else { fSuccess = pDBSession->FInit(this, _Credentials); } if (!fSuccess) { delete pDBSession; RRETURN( E_OUTOFMEMORY ); } // // get requested interface pointer on DBSession // hr = pDBSession->QueryInterface( riid, (void **) ppDBSession ); if( FAILED( hr ) ) { delete pDBSession; RRETURN( hr ); } pDBSession->Release(); RRETURN( S_OK ); } //+----------------------------------------------------------------------------- // // Function: CDSOObject::CDSOObject // // Synopsis: Constructor // // Arguments: // pUnkOuter Outer Unkown Pointer // // Returns: // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- CDSOObject::CDSOObject( LPUNKNOWN pUnkOuter ) { // Initialize simple member vars _pUnkOuter = pUnkOuter ? pUnkOuter : (IDBInitialize FAR *) this; _fDSOInitialized = FALSE; _cSessionsOpen = FALSE; _pUtilProp = NULL; _ThreadToken = NULL; // Set defaults _Credentials.SetUserName(NULL); _Credentials.SetPassword(NULL); _Credentials.SetAuthFlags(0); ENLIST_TRACKING(CDSOObject); // make sure DLL isn't unloaded until all data source objects are destroyed InterlockedIncrement(&glnOledbObjCnt); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::~CDSOObject // // Synopsis: Destructor // // Arguments: // // Returns: // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- CDSOObject::~CDSOObject( ) { // // Free properties management object // delete _pUtilProp; if (_ThreadToken) CloseHandle(_ThreadToken); InterlockedDecrement(&glnOledbObjCnt); } //+--------------------------------------------------------------------------- // // Function: CDSOObject::FInit // // Synopsis: Initialize the data source Object // // Arguments: // // Returns: // Did the Initialization Succeed // TRUE Initialization succeeded // FALSE Initialization failed // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- BOOL CDSOObject::FInit( void ) { HRESULT hr; // // Allocate properties management object // _pUtilProp = new CUtilProp(); if( !_pUtilProp ) return FALSE; hr = _pUtilProp->FInit(&_Credentials); BAIL_ON_FAILURE( hr ); return TRUE; error: return FALSE; } //+--------------------------------------------------------------------------- // // Function: CDSOObject::QueryInterface // // Synopsis: Returns a pointer to a specified interface. Callers use // QueryInterface to determine which interfaces the called object // supports. // // Arguments: // riid Interface ID of the interface being queried for // ppv Pointer to interface that was instantiated // // Returns: // S_OK Interface is supported and ppvObject is set. // E_NOINTERFACE Interface is not supported by the object // E_INVALIDARG One or more arguments are invalid. // // Modifies: // // History: 08-28-96 ShankSh Created. // //---------------------------------------------------------------------------- STDMETHODIMP CDSOObject::QueryInterface(REFIID iid, LPVOID FAR* ppv) { if( ppv == NULL ) RRETURN( E_INVALIDARG ); if( IsEqualIID(iid, IID_IUnknown) ) { *ppv = (IDBInitialize FAR *) this; } else if( IsEqualIID(iid, IID_IDBInitialize) ) { *ppv = (IDBInitialize FAR *) this; } else if( IsEqualIID(iid, IID_IDBProperties) ) { *ppv = (IDBProperties FAR *) this; } else if( _fDSOInitialized && IsEqualIID(iid, IID_IDBCreateSession) ) { *ppv = (IDBCreateSession FAR *) this; } else if( IsEqualIID(iid, IID_IPersist) ) { *ppv = (IPersist FAR *) this; } else { *ppv = NULL; return E_NOINTERFACE; } AddRef(); return NOERROR; }