|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// interface implementation
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Opens and returns a rowset that includes all rows from a single base table
//
// HRESULT
// S_OK The method succeeded
// E_INVALIDARG pTableID was NULL
// E_FAIL Provider-specific error
// DB_E_NOTABLE Specified table does not exist in current Data Data Source object
// E_OUTOFMEMORY Out of memory
// E_NOINTERFACE The requested interface was not available
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CImpIOpenRowset::OpenRowset( IUnknown* pUnkOuter, // IN Controlling unknown, if any
DBID* pTableID, // IN table to open
DBID* pIndexID, // IN DBID of the index
REFIID riid, // IN interface to return
ULONG cPropertySets, // IN count of properties
DBPROPSET rgPropertySets[], // INOUT array of property values
IUnknown** ppRowset // OUT where to return interface
) { CRowset* pRowset = NULL; HRESULT hr = S_OK; HRESULT hrProp = S_OK ; BOOL bRowRequested = FALSE; CRow* pRow = NULL; ULONG cErrors = 0; CSetStructuredExceptionHandler seh;
TRY_BLOCK;
assert( m_pObj ); assert( m_pObj->m_pUtilProp );
//=====================================================================
// NULL out-params in case of error
//=====================================================================
if( ppRowset ) { *ppRowset = NULL; }
// Seriliaze the object
CAutoBlock cab(m_pObj->GetCriticalSection());
// Clear Error information
g_pCError->ClearErrorInfo();
//=====================================================================
// Check Arguments
//=====================================================================
if ( !pTableID && !pIndexID ) { hr = E_INVALIDARG; // return g_pCError->PostHResult(E_INVALIDARG,&IID_IOpenRowset);
} else if ( riid == IID_NULL) { hr = E_NOINTERFACE; // return g_pCError->PostHResult(E_NOINTERFACE,&IID_IOpenRowset) ;
} else //==========================================================
// We only accept NULL for pIndexID at this present time
//==========================================================
if( pIndexID ) { hr = DB_E_NOINDEX; // return g_pCError->PostHResult(DB_E_NOINDEX,&IID_IOpenRowset) ;
} else //===================================================================================
// We do not allow the riid to be anything other than IID_IUnknown for aggregation
//===================================================================================
if ( (pUnkOuter) && (riid != IID_IUnknown) ) { hr = DB_E_NOAGGREGATION; // return g_pCError->PostHResult(DB_E_NOAGGREGATION,&IID_IOpenRowset) ;
} else //==============================================
// validate the property sets to be set
//==============================================
if( SUCCEEDED(hr = m_pObj->m_pUtilProp->SetPropertiesArgChk(cPropertySets, rgPropertySets,TRUE)) ) {
//=================================================================
// If the eKind is not known to use, basically it means we have no
// table identifier
//=================================================================
if ( (!pTableID ) || ( pTableID->eKind != DBKIND_NAME ) || ( (pTableID->eKind == DBKIND_NAME) && (!(pTableID->uName.pwszName)) ) || ( wcslen(pTableID->uName.pwszName) == 0 ) || ( wcslen(pTableID->uName.pwszName) > _MAX_FNAME ) ) { hr = DB_E_NOTABLE ; } else {
if( riid == IID_IRow || riid == IID_IRowChange || GetIRowProp(cPropertySets,rgPropertySets) == TRUE) { bRowRequested = TRUE; } // If rowset is to be created then create a new rowset
if( bRowRequested == FALSE) { //===============================================================================
// open and initialize a rowset\cursor object
//===============================================================================
// pRowset = new CRowset(pUnkOuter,NO_QUALIFIERS,(LPWSTR)(pTableID->uName.pwszName),m_pObj);
try { pRowset = new CRowset(pUnkOuter,m_pObj); } catch(...) { SAFE_DELETE_PTR(pRowset); throw;; }
if (!pRowset) { hr = E_OUTOFMEMORY ; } else { //===========================================================================
// if properties failed or ppRowset NULL
//===========================================================================
hr = pRowset->InitRowset(cPropertySets, rgPropertySets,(LPWSTR)(pTableID->uName.pwszName)); if( (SUCCEEDED(hr)) ) { if(hr != S_OK) { cErrors++; } //=======================================================================
// get requested interface pointer on rowset\cursor
//=======================================================================
if(ppRowset != NULL) { hr = pRowset->QueryInterface( riid, (void **) ppRowset ); if (SUCCEEDED( hr )) { //===================================================================
//Assign creator pointer. Used for IRowsetInfo::GetSpecification
//===================================================================
// m_pObj->m_fRowsetCreated = TRUE;
} } else { SAFE_DELETE_PTR(pRowset); hr = cErrors > 0 ? DB_S_ERRORSOCCURRED : S_OK; } } } // else for failure of allocation of pRowset
} // Create a row
else { CURLParser urlParser; VARIANT varNameSpace; BSTR strClassName,strObject;
strObject = Wmioledb_SysAllocString(pTableID->uName.pwszName); VariantInit(&varNameSpace);
// Get the namespace of the datasource
m_pObj->GetDataSrcProperty(DBPROP_INIT_DATASOURCE,varNameSpace);
hr = urlParser.SetURL(strObject); SAFE_FREE_SYSSTRING(strObject); if(SUCCEEDED(hr)) {
// urlParser.SetNameSpace(varNameSpace.bstrVal);
urlParser.GetClassName(strClassName); urlParser.GetPath(strObject);
try { // Create a new row on the instance
pRow = new CRow(pUnkOuter,m_pObj); } catch(...) { SAFE_DELETE_PTR(pRow); throw; } if(pRow == NULL) { hr = E_OUTOFMEMORY; } else { // call this function to initialize the row
hr = pRow->InitRow(strObject,strClassName); if(hr == S_OK) { // QI for the required interface
hr = pRow->QueryInterface(riid,(void **)ppRowset); }
} } // Freeing the variables
VariantClear(&varNameSpace); SysFreeString(strClassName); SysFreeString(strObject); } // end of creating row
} // if valid table name
}
if( FAILED(hr ) ) { SAFE_DELETE_PTR( pRowset ); SAFE_DELETE_PTR( pRow ); } if(hr == S_OK && cErrors > 0) { hr = DB_S_ERRORSOCCURRED; }
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,&IID_IOpenRowset);
CATCH_BLOCK_HRESULT(hr,L"IOpenRowset::OpenRowset"); return hr;
} /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to get a DBPROP_IRow property
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CImpIOpenRowset::GetIRowProp(ULONG cPropertySets, // IN count of properties
DBPROPSET rgPropertySets[]) { BOOL bRet = FALSE;
for( ULONG lIndex = 0 ; lIndex < cPropertySets ; lIndex++) { if(rgPropertySets[lIndex].guidPropertySet == DBPROPSET_ROWSET) { for ( ULONG nPropIndex = 0 ; nPropIndex < rgPropertySets[lIndex].cProperties ; nPropIndex++ ) { if(rgPropertySets[lIndex].rgProperties[nPropIndex].dwPropertyID == DBPROP_IRow && rgPropertySets[lIndex].rgProperties[nPropIndex].vValue.boolVal == VARIANT_TRUE) { bRet = TRUE; } // if DBPROP_IRow is true;
}// for loop
} // if propertyset is DBPROPSET_ROWSET
} // outer for loop
return bRet; }
|