/////////////////////////////////////////////////////////////////////////////////// // // Microsoft WMIOLE DB Provider // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved. // // CRowset object implementation // // /////////////////////////////////////////////////////////////////////////////////// #include "headers.h" #include "WmiOleDBMap.h" ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Constructor ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// CRowset::CRowset(LPUNKNOWN pUnkOuter,PCDBSESSION pObj,CWbemConnectionWrapper *pCon ) : CBaseRowObj( pUnkOuter) { //=============================================================== // Initialize simple member vars //=============================================================== InitVars(); m_pCreator = pObj; m_pCreator->GetOuterUnknown()->AddRef(); //=============================================== // Add this rowset ot list of open rowset //=============================================== m_pCreator->AddRowset(this); m_pCon = pCon; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Constructor for this class , Initializing recordset for Qualifiers // ///////////////////////////////////////////////////////////////////////////////////////////////// CRowset::CRowset(LPUNKNOWN pUnkOuter,ULONG uQType, LPWSTR PropertyName,PCDBSESSION pObj , CWmiOleDBMap *pMap) : CBaseRowObj(NULL) { //=============================================================== // Initialize simple member vars //=============================================================== InitVars(); m_pCreator = pObj; m_pCreator->GetOuterUnknown()->AddRef(); //=============================================== // Add this rowset ot list of open rowset //=============================================== m_pCreator->AddRowset(this); m_pMap = pMap; m_pMap->AddRef(); //====================================================================== // set the flag which indicates that this Rowset is a child recordsets; //====================================================================== m_bIsChildRs = TRUE; // Initializing the Qualifier properties m_uRsType = uQType; if ( m_uRsType == PROPERTYQUALIFIER) { m_strPropertyName = Wmioledb_SysAllocString(PropertyName); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to Initialize all the member variables ///////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CRowset::InitVars() { m_cCols = m_cCols = m_cNestedCols = 0L; //=============================================================== // set the flag which indicates that this Rowset is not a child rowset //=============================================================== m_bIsChildRs = FALSE; //=============================================================== // Intialize buffered row count + pointers to allocated memory //=============================================================== m_cRows = 0; m_cbRowSize = 0; m_irowMin = 0; m_ulRowRefCount = 0; m_dwStatus = 0; m_bHelperFunctionCreated= FALSE; m_hLastChapterAllocated = 0; m_ulProps = 0; m_ulLastFetchedRow = 0; m_hRow = 0; m_uRsType = 0; m_cRef = 0L; m_bIsChildRs = FALSE; m_FetchDir = FETCHDIRNONE; m_lLastFetchPos = 0; m_lRowCount = -1; m_hRowLastFetched = 0; //=============================================================== // Initially, NULL all contained interfaces //=============================================================== m_pIAccessor = (PIMPIACCESSOR)NULL; m_pIColumnsInfo = NULL; m_pIConvertType = NULL; m_pIRowset = NULL; m_pIRowsetChange = NULL; m_pIRowsetIdentity = NULL; m_pIRowsetInfo = NULL; m_pIChapteredRowset = NULL; m_pIGetRow = NULL; m_pIRowsetRefresh = NULL; m_pRowFetchObj = NULL; m_ppChildRowsets = NULL; m_pInstance = NULL; m_pParentCmd = NULL; m_pIBuffer = NULL; m_pLastBindBase = NULL; m_pRowData = NULL; m_pUtilProp = NULL; m_pChapterMgr = NULL; m_pMap = NULL; m_pCreator = NULL; m_pHashTblBkmark = NULL; m_InstMgr = NULL; m_pISupportErrorInfo = NULL; //=============================================================== // Increment global object count. //=============================================================== InterlockedIncrement(&g_cObj); } ///////////////////////////////////////////////////////////////////////////////////////////////// // Destructor for this class ///////////////////////////////////////////////////////////////////////////////////////////////// CRowset::~CRowset( void ) { //============================================================== // Release all the open Rows //============================================================== ReleaseAllRows(); //================================================ // If Slot list is allocated, release them //================================================ if (NULL != m_pIBuffer) { ReleaseSlotList( m_pIBuffer ); } if ( m_uRsType == PROPERTYQUALIFIER) { SysFreeString(m_strPropertyName); } //=============================================================== // Free pointers. //=============================================================== SAFE_DELETE_PTR( m_pUtilProp ); //=============================================================== // NOTE: m_pMap releases the class ptr in destructor //=============================================================== m_pMap->Release(); SAFE_DELETE_PTR(m_pHashTblBkmark); //=============================================================== // Free contained interfaces //=============================================================== SAFE_DELETE_PTR( m_pIAccessor ); SAFE_DELETE_PTR( m_pIColumnsInfo ); SAFE_DELETE_PTR( m_pIConvertType ); SAFE_DELETE_PTR( m_pIRowset ); SAFE_DELETE_PTR( m_pIRowsetChange ); SAFE_DELETE_PTR( m_pIRowsetIdentity ); SAFE_DELETE_PTR( m_pIRowsetInfo ); SAFE_DELETE_PTR( m_pIChapteredRowset); SAFE_DELETE_PTR( m_pIGetRow); SAFE_DELETE_PTR( m_pIRowsetRefresh); SAFE_DELETE_PTR(m_pISupportErrorInfo); SAFE_DELETE_PTR(m_pRowData); SAFE_DELETE_PTR(m_pRowFetchObj); SAFE_DELETE_PTR(m_InstMgr); //=============================================================== // Decrement the DBSession Count. GetSpecification is not // possible anymore //=============================================================== if( m_pCreator ) { m_pCreator->GetOuterUnknown()->Release(); } //=============================================================== // If rowset is created by command then, decrement the number of rowsets // opened by the rowset and release the command pointer //=============================================================== if(m_pParentCmd != NULL) { m_pParentCmd->DecrementOpenRowsets(); m_pParentCmd->GetOuterUnknown()->Release(); } SAFE_DELETE_PTR(m_pChapterMgr); //================================================ // Release child rowsets //================================================ if(m_ppChildRowsets != NULL) { for(UINT nIndex = 0 ; nIndex < m_cTotalCols ; nIndex++) { if(m_ppChildRowsets[nIndex] != NULL) { m_ppChildRowsets[nIndex]->Release(); } } delete m_ppChildRowsets; } if(m_bNewConAllocated) { SAFE_DELETE_PTR(m_pCon); } //=============================================================== // Decrement global object count. //=============================================================== InterlockedDecrement(&g_cObj); } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Returns a pointer to a specified interface. Callers use QueryInterface to determine which // interfaces the called object supports. // Sucess of QI for some of the interfaces depend on some of the properties // // HRESULT indicating the status of the method // 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. // ///////////////////////////////////////////////////////////////////////////////////////////////// STDMETHODIMP CRowset::QueryInterface ( REFIID riid, LPVOID * ppv ) { HRESULT hr = S_OK; //====================================================== // Check parameters, if not valid return //====================================================== if (NULL == ppv) { hr = E_INVALIDARG ; } else { //====================================================== // Place NULL in *ppv in case of failure //====================================================== *ppv = NULL; //====================================================== // This is the non-delegating IUnknown implementation //====================================================== if (riid == IID_IUnknown) { *ppv = (LPVOID) this; } else if (riid == IID_IAccessor) { *ppv = (LPVOID) m_pIAccessor; } else if (riid == IID_IColumnsInfo) { *ppv = (LPVOID) m_pIColumnsInfo; } else if (riid == IID_IConvertType) { *ppv = (LPVOID) m_pIConvertType; } else if (riid == IID_IRowset) { *ppv = (LPVOID) m_pIRowset; } else if (riid == IID_IRowsetLocate && (m_ulProps & IROWSETLOCATE)) { *ppv = (LPVOID) m_pIRowset; } else if (riid == IID_ISourcesRowset) { *ppv = (LPVOID) m_pIRowset; } else if (riid == IID_IRowsetChange && (m_ulProps & IROWSETCHANGE)) { *ppv = (LPVOID) m_pIRowsetChange; } else if (riid == IID_IRowsetIdentity) { *ppv = (LPVOID) m_pIRowsetIdentity; } else if (riid == IID_IRowsetInfo) { *ppv = (LPVOID) m_pIRowsetInfo; } else if (riid == IID_IChapteredRowset && (m_ulProps & ICHAPTEREDROWSET)) { *ppv = (LPVOID) m_pIChapteredRowset; } else if (riid == IID_IGetRow && (m_ulProps & IGETROW)) { *ppv = (LPVOID) m_pIGetRow; } else if(riid == IID_IRowsetRefresh && (m_ulProps & IROWSETREFRESH)) { *ppv = (LPVOID)m_pIRowsetRefresh; } else if(riid == IID_ISupportErrorInfo) { *ppv = (LPVOID)m_pISupportErrorInfo; } //====================================================== // If we're going to return an interface, AddRef first //====================================================== if (*ppv) { ((LPUNKNOWN) *ppv)->AddRef(); hr = S_OK ; } else { hr = E_NOINTERFACE; } } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Increments a persistence count for the object // // Returns Current reference count // ///////////////////////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CRowset::AddRef( void ) { return InterlockedIncrement((long*)&m_cRef); } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Decrements a persistence count for the object and if persistence count is 0, the object // destroys itself. // ///////////////////////////////////////////////////////////////////////////////////////////////// STDMETHODIMP_( ULONG ) CRowset::Release( void ) { if (!InterlockedDecrement((long*)&m_cRef)) { //=========================================================== // Mark the session as not having an open rowset anymore //=========================================================== this->m_pCreator->RemoveRowset(this); // this->m_pCreator->DecRowsetCount(); delete this; return 0; } return m_cRef; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Initialize the rowset for representing a row. This rowset will not be opened as a child rowset // This is used when rowset is opened on a qualifier // // // Did the Initialization Succeed // S_OK Initialization succeeded // E_INVALIDARG Some input data are incorrect // E_OUTOFMEMORY Out of memory when allocate memory for member data // ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InitRowsetForRow(LPUNKNOWN pUnkOuter , const ULONG cPropertySets, const DBPROPSET rgPropertySets[] , CWbemClassWrapper *pInst) { HRESULT hr = S_OK; HROW hRowCurrent = 0; CBSTR strKey; //================================================ // Initialize the member variables //================================================ m_bIsChildRs = FALSE; //========================== // Inititialize the rowset //========================== if(S_OK == (hr =InitRowset(cPropertySets,rgPropertySets))) { m_pMap->GetInstanceKey(pInst,strKey); m_pInstance = pInst; //=========================================================================== // if there is atleast one row retrieved and there are neseted columns // then allocate rows for the child recordsets //=========================================================================== if(m_cNestedCols > 0 ) { if(m_ppChildRowsets == NULL) { AllocateAndInitializeChildRowsets(); } //===================================================================== // Fill the HCHAPTERS for the column //===================================================================== if(S_OK != (hr = FillHChaptersForRow(pInst,strKey))) { hr = E_FAIL; } } if( FAILED(hr = CreateHelperFunctions())) { return hr; } m_bHelperFunctionCreated = TRUE; } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Overloaded Rowset Initialization function to initialize rowset created from a command object // // Did the Initialization Succeed // S_OK Initialization succeeded // E_INVALIDARG Some input data are incorrect // E_OUTOFMEMORY Out of memory when allocate memory for member data // ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InitRowset( const ULONG cPropertySets, const DBPROPSET rgPropertySets[],DWORD dwFlags, CQuery* p,PCCOMMAND pCmd ) { HRESULT hr = S_OK; //============================================ // Set the qualifier flags //============================================ dwFlags = (long)dwFlags == -1 ? GetQualifierFlags() : dwFlags; //================================================================== // Create a CWmiOleDBMap class with the appropriate constructor //================================================================== m_pMap = new CWmiOleDBMap; if( m_pMap != NULL) { if(SUCCEEDED(hr = m_pMap->FInit(dwFlags,p,m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon))) { m_pMap->AddRef(); m_pParentCmd = pCmd; m_uRsType = p->GetType(); // If it is a COMMAND_ROWSET or METHOD_ROWSET //============================================ // To hold the parent command reference //============================================ m_pParentCmd->GetOuterUnknown()->AddRef(); //===================================================== // Call this function to do the rest of initialization //===================================================== hr = InitRowset(cPropertySets,rgPropertySets); } } else { hr = E_OUTOFMEMORY; } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Overloaded Rowset Initialization function // This function is called for (1) Schema Rowsets via CSchema // // Did the Initialization Succeed // S_OK Initialization succeeded // E_INVALIDARG Some input data are incorrect // E_OUTOFMEMORY Out of memory when allocate memory for member data // ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InitRowset( int nBaseType,const ULONG cPropertySets, const DBPROPSET rgPropertySets[],LPWSTR TableID, DWORD dwFlags, LPWSTR SpecificTable ) { HRESULT hr = S_OK; //============================================ // Set the qualifier flags //============================================ dwFlags = (long)dwFlags == -1 ? GetQualifierFlags() : dwFlags; //================================================================== // Create a CWmiOleDBMap class with the appropriate constructor //================================================================== m_pMap = new CWmiOleDBMap; if( m_pMap != NULL) { if(SUCCEEDED(hr = m_pMap->FInit(nBaseType, dwFlags, TableID, SpecificTable, m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon))) { m_pMap->AddRef(); m_uRsType = SCHEMA_ROWSET; //===================================================== // Call this function to do the rest of initialization //===================================================== hr = InitRowset(cPropertySets,rgPropertySets); } } else { hr = E_OUTOFMEMORY; } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Overloaded Rowset Initialization function // This function is called for (1) Schema Rowsets // (2) rowsets created from IOpenrowset:OpenRowset // // Did the Initialization Succeed // S_OK Initialization succeeded // E_INVALIDARG Some input data are incorrect // E_OUTOFMEMORY Out of memory when allocate memory for member data // ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InitRowset( const ULONG cPropertySets, const DBPROPSET rgPropertySets[],LPWSTR TableID,BOOL fSchema , DWORD dwFlags ) { HRESULT hr = S_OK; VARIANT vValue; VariantInit(&vValue); //============================================ // Set the qualifier flags //============================================ dwFlags = (long)dwFlags == -1 ? GetQualifierFlags() : dwFlags; //================================================================== // Create a CWmiOleDBMap class with the appropriate constructor //================================================================== m_pMap = new CWmiOleDBMap; if( m_pMap != NULL) { if(wcscmp(TableID,OPENCOLLECTION) == 0) { INSTANCELISTTYPE instType = GetObjectTypeProp(cPropertySets,rgPropertySets); hr = m_pMap->FInit(dwFlags,TableID,m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon,instType); } else { hr = m_pMap->FInit(dwFlags,TableID,m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon); } if(SUCCEEDED(hr)) { m_pMap->AddRef(); m_uRsType = fSchema == TRUE ? SCHEMA_ROWSET : 0; //===================================================== // Call this function to do the rest of initialization //===================================================== hr = InitRowset(cPropertySets,rgPropertySets); } } else { hr = E_OUTOFMEMORY; } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Overloaded Rowset Initialization function // This function is called for (1) ROwsets created for Scope/Container // // Did the Initialization Succeed // S_OK Initialization succeeded // E_INVALIDARG Some input data are incorrect // E_OUTOFMEMORY Out of memory when allocate memory for member data // ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InitRowset( const ULONG cPropertySets, const DBPROPSET rgPropertySets[], LPWSTR strObjectID, LPWSTR strObjectToOpen, INSTANCELISTTYPE objInstListType , DWORD dwFlags) { HRESULT hr = S_OK; WCHAR *pstrTableID = NULL; CWbemConnectionWrapper *pCon = m_pCon; pstrTableID = strObjectID; //============================================ // Set the qualifier flags //============================================ dwFlags = (long)dwFlags == -1 ? GetQualifierFlags() : dwFlags; if(!pstrTableID) { pstrTableID = new WCHAR[wcslen(OPENCOLLECTION) + 1]; if(pstrTableID) { wcscpy(pstrTableID,OPENCOLLECTION); } else { hr = E_OUTOFMEMORY; } } if(SUCCEEDED(hr) && strObjectToOpen) // wbem_wcsincmp(m_pCreator->m_pCDataSource->m_pWbemWrap->GetNamespace(),strObjectID,wcslen(m_pCreator->m_pCDataSource->m_pWbemWrap->GetNamespace()))) { m_pCon = new CWbemConnectionWrapper; if(m_pCon) { hr = m_pCon->FInit(pCon != NULL ? pCon : m_pCreator->m_pCDataSource->m_pWbemWrap, strObjectToOpen,objInstListType); m_bNewConAllocated = TRUE; } else { hr = E_OUTOFMEMORY; } } if(SUCCEEDED(hr)) { //================================================================== // Create a CWmiOleDBMap class with the appropriate constructor //================================================================== m_pMap = new CWmiOleDBMap; if( m_pMap != NULL) { if(SUCCEEDED(hr = m_pMap ->FInit(dwFlags, pstrTableID, m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon, objInstListType))) { m_pMap->AddRef(); //===================================================== // Call this function to do the rest of initialization //===================================================== hr = InitRowset(cPropertySets,rgPropertySets); } } else { hr = E_OUTOFMEMORY; } } if(!strObjectID) { SAFE_DELETE_ARRAY(pstrTableID); } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Initialize the rowset Object // // Did the Initialization Succeed // S_OK Initialization succeeded // E_INVALIDARG Some input data are incorrect // E_OUTOFMEMORY Out of memory when allocate memory for member data // ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InitRowset( const ULONG cPropertySets, const DBPROPSET rgPropertySets[] ) { HRESULT hr = S_OK; bool bRowChange = true; ULONG cErrors = 0; //============================================================================ // allocate utility object that manages our properties //============================================================================ m_pUtilProp = new CUtilProp; if ( m_pUtilProp == NULL ) { hr = E_OUTOFMEMORY; } else // NTRaid: 136443 // 07/05/00 if(SUCCEEDED(hr = m_pUtilProp->FInit(ROWSETPROP))) { //07/06/00 // NTRaid : 134987 if(m_uRsType == SCHEMA_ROWSET) { hr = InitializePropertiesForSchemaRowset(); } else if(m_uRsType == COMMAND_ROWSET ) { hr = InitializePropertiesForCommandRowset(); } else if(m_uRsType == METHOD_ROWSET) { hr = InitializePropertiesForMethodRowset(); } //============================================================================ // Set rowset properties // May be setting of optional properties might have failed and so we can continue //============================================================================ // hr = SetRowsetProperties(cPropertySets,rgPropertySets); if(SUCCEEDED(hr) && SUCCEEDED(hr = SetRowsetProperties(cPropertySets,rgPropertySets))) { if(hr != S_OK) { cErrors++; } //=================================================================================== // Call this function to initialize some of the rowset properties, set some flags // and set flags on CWmiOledbMap object //=================================================================================== InitializeRowsetProperties(); //==================================================================== /// Get property and Set Serach Preferences //==================================================================== hr = SetSearchPreferences(); //=================================================================================== // Get column the information for the rowset //=================================================================================== if( S_OK == (hr = CBaseRowObj::GetColumnInfo())) { //============================================================= // Initialize the first instance to zero if the rowset is // not a child rowset //============================================================= if(m_bIsChildRs != TRUE && ( m_uRsType == 0 || m_uRsType == SCHEMA_ROWSET || m_uRsType == COMMAND_ROWSET || m_uRsType == METHOD_ROWSET)) { hr = ResetInstances(); } else //====================================================================================== // Create the chaptermanager with CRowsetpointers only if the rowset is a child rowset //====================================================================================== if(m_bIsChildRs == TRUE) { m_pChapterMgr = new CChapterMgr(); if ( !m_pChapterMgr ) { hr = E_OUTOFMEMORY; } } if(!FAILED(hr)) { //======================================================= // Call this function to allocate memory for all // contained interfaces //======================================================= hr = AllocateInterfacePointers(); } } // if( S_OK == (hr = CBaseRowObj::GetColumnInfo())) } // if(!FAILED(hr)) after Setting the rowset properties //=========================================================================== // Call this function to increment the number of rowsets opened by command // if rowset is opened by command //=========================================================================== if( SUCCEEDED(hr)) { //========================================================== // Call this function to initialize the ISupportErrorInfo; //========================================================== hr = AddInterfacesForISupportErrorInfo(); if(m_pParentCmd != NULL) { m_pParentCmd->IncrementOpenRowsets(); } if(cErrors > 0) { hr = DB_S_ERRORSOCCURRED; } } } // If Succeeded(hr) after allocating memory for utilprop return hr; } /////////////////////////////////////////////////////////////////////////////////////////////// // Allocate memory for the different interfaces /////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::AllocateInterfacePointers() { HRESULT hr = S_OK; BOOL bRowChange = TRUE; //=========================================================================================== // Allocate contained interface objects // Note that our approach is simple - we always create *all* of the Rowset interfaces // If our properties were read\write (i.e., could be set), we would need to // consult properties to known which interfaces to create. // Also, none of our interfaces conflict. If any did conflict, then we could // not just blindly create them all. //=========================================================================================== m_pIAccessor = new CImpIAccessor( this ); if( m_pIAccessor ) { hr = m_pIAccessor->FInit() ; } else hr = E_OUTOFMEMORY; if(SUCCEEDED(hr)) { m_pIColumnsInfo = new CImpIColumnsInfo( this ); m_pIConvertType = new CImpIConvertType(this); m_pIRowset = new CImpIRowsetLocate( this ); if(m_ulProps & IROWSETCHANGE ) { m_pIRowsetChange = new CImpIRowsetChange( this ); } m_pIRowsetIdentity = new CImpIRowsetIdentity( this ); m_pIRowsetInfo = new CImpIRowsetInfo( this ); m_pIChapteredRowset = new CImpIChapteredRowset(this); m_pIGetRow = new CImpIGetRow(this); m_pIRowsetRefresh = new CImplIRowsetRefresh(this); m_pISupportErrorInfo = new CImpISupportErrorInfo(this); //=============================================================== // If rowset is pointing to qualifier then instantiate the // qualifier fetch object //=============================================================== if(m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER) { m_pRowFetchObj = (CRowFetchObj *)new CQualifierRowFetchObj; } else { m_pRowFetchObj = (CRowFetchObj *)new CInstanceRowFetchObj; } } if(SUCCEEDED(hr)) { if( (m_pIRowsetChange == NULL) && ((m_ulProps & IROWSETCHANGE) != 0)) { bRowChange = FALSE; } //=========================================================================================== // if all interfaces were created, return success //=========================================================================================== if( ! (m_pIAccessor && m_pIColumnsInfo && m_pIConvertType && m_pIRowset && bRowChange && m_pIRowsetIdentity && m_pIRowsetInfo && m_pIChapteredRowset && m_pIRowsetRefresh && m_pISupportErrorInfo)) { hr = E_OUTOFMEMORY; } } return hr; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to initialize Rowset properties and also set some of the flags on CWMIOledbMap accordingly ////////////////////////////////////////////////////////////////////////////////////////////////////////// void CRowset::InitializeRowsetProperties() { HRESULT hr = S_OK; VARIANT varProp; VariantInit(&varProp); //=========================================================================================== // Initialize the common rowset properties ( boolean properties) // and put that in the member variable //=========================================================================================== GetCommonRowsetProperties(); //=========================================================================================== // set the forwardonly flag of enumerator to null depending on // the properties //=========================================================================================== // NTRaid 14199 // 07/14/2000. The navigation flags of the parent rowset for qualifier rowset was getting changed if(!((CANSCROLLBACKWARDS & m_ulProps) || (CANFETCHBACKWARDS & m_ulProps) || (BOOKMARKPROP & m_ulProps)) || (m_uRsType == METHOD_ROWSET) && (m_uRsType != PROPERTYQUALIFIER || m_uRsType != CLASSQUALIFIER)) { m_pMap->SetNavigationFlags(WBEM_FLAG_FORWARD_ONLY); m_ulProps = m_ulProps & ~CANSCROLLBACKWARDS; m_ulProps = m_ulProps & ~CANFETCHBACKWARDS; m_ulProps = m_ulProps & ~BOOKMARKPROP; m_ulProps = m_ulProps & ~IROWSETLOCATE; } //=========================================================================================== // If the custom WMIOLEDB property FETCHDEEP is set , then set the other OLEDB props // which reflects the behaviour of the rowset //=========================================================================================== if(FETCHDEEP & m_ulProps) { varProp.vt = VT_BOOL; varProp.boolVal = VARIANT_TRUE; m_pMap->SetQueryFlags(WBEM_FLAG_DEEP); //=========================================================================================== // If enumeration is opened as FLAG_DEEP, it is bidirectional // So set the respective properties //=========================================================================================== SetRowsetProperty(DBPROP_CANSCROLLBACKWARDS,varProp); SetRowsetProperty(DBPROP_CANFETCHBACKWARDS,varProp); } VariantClear(&varProp); //=========================================================================================== // Get the DataSource property to check if system Properties is to be fetched? //=========================================================================================== m_pCreator->GetDataSrcProperty(DBPROP_WMIOLEDB_SYSTEMPROPERTIES,varProp); if( varProp.boolVal == VARIANT_TRUE) { m_pMap->SetSytemPropertiesFlag(TRUE); } VariantClear(&varProp); } ///////////////////////////////////////////////////////////////////////////////////////////////////// // Function to add interfaces to ISupportErrorInfo interface ///////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::AddInterfacesForISupportErrorInfo() { HRESULT hr = S_OK; if(SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IAccessor)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IColumnsInfo)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IConvertType)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowset)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_ISourcesRowset)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowsetIdentity))) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowsetInfo); } if(SUCCEEDED(hr) && (m_ulProps & IROWSETLOCATE)) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowsetLocate); } if(SUCCEEDED(hr) && (m_ulProps & IROWSETCHANGE)) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowsetChange); } if(SUCCEEDED(hr) && (m_ulProps & ICHAPTEREDROWSET)) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IChapteredRowset); } if(SUCCEEDED(hr) && (m_ulProps & IGETROW)) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IGetRow); } if(SUCCEEDED(hr) && (m_ulProps & IROWSETREFRESH)) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowsetRefresh); } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Creates DBCOLINFO structures for each column in the result set. // // HRESULT // S_OK Column Info Obtained // E_FAIL Problems getting Column Info // /////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GatherColumnInfo() { //======================================================= // Call GatherColumnInfo() on the base object //======================================================= HRESULT hr = CBaseRowObj::GatherColumnInfo(); //============================================================= // Initialize the first instance to zero if the rowset is // not a child rowset //============================================================= if(hr == S_OK && m_bIsChildRs != TRUE) { ResetInstances(); } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////// // // Creates Helper classes that are needed to manage the Rowset Object // // HRESULT // S_OK Helper classes created // E_FAIL Helper classes were not created // // NTRaid : 142133 & 141923 // 07/12/00 ///////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::CreateHelperFunctions ( void ) { HRESULT hr = E_OUTOFMEMORY; if(m_cTotalCols == 0) { hr = S_OK; } else //============================================================================ // List of free slots. // This manages the allocation of sets of contiguous rows. //============================================================================ if (SUCCEEDED(hr = InitializeSlotList( MAX_TOTAL_ROWBUFF_SIZE / m_cbRowSize, m_cbRowSize, g_dwPageSize, m_pIAccessor->GetBitArrayPtr(),&m_pIBuffer, &m_rgbRowData ))) { //============================================================================ // Locate some free slots. Should be at very beginning. // This tells us which row we will bind to: m_irowMin. // After getting the slot just release it as this was just a test //============================================================================ if (SUCCEEDED( hr = GetNextSlots( m_pIBuffer, 1, (HSLOT *)&m_irowMin ))) { hr = ReleaseSlots( m_pIBuffer, m_irowMin, 1 ); } } if(SUCCEEDED(hr)) { //================================================= // Allocate and initialize rowdata manager //================================================= m_pRowData = new CRowDataMemMgr; if( m_pRowData != NULL) { //================================================= // Set the number of columns in row //================================================= m_pRowData->AllocRowData(m_cTotalCols); hr = S_OK; //================================================= // Allocate memory for instance manager //================================================= m_InstMgr = new CWMIInstanceMgr; if( m_InstMgr != NULL) { //============================================================== // If bookmark is required then allocate an new hashtbl class //============================================================== if(m_ulProps & BOOKMARKPROP) { m_pHashTblBkmark = new CHashTbl; if(m_pHashTblBkmark != NULL) { //================================================= // Initialize the hashtable //================================================= m_pHashTblBkmark->FInit((PLSTSLOT)m_pIBuffer); //================================================= // Call this function to get the number of rows //================================================= GetRowCount(); hr = S_OK; } // if(m_HashTblBkmark != NULL) } // if( bookmark property is set) } // if ( instance manage is allocated correctly) else { hr = E_OUTOFMEMORY; } } // if( m_pRowData != NULL) } // GetNextSlots succeeded return hr ; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // Establishes data offsets and type for the routines to place the data // // HRESULT // S_OK Bindings set fine // E_FAIL Bindings could not be set // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::Rebind( BYTE *pBase ) // IN Base pointer for Data Area { HRESULT hr= 0; UWORD icol; COLUMNDATA *pColumn; //============================================================================== // Bind result set columns. // Use established types and sizes and offsets. // Bind to internal row buffer, area beginning with 'pRowBuff'. // // For each column, bind it's data as well as length. // Offsets point to start of COLUMNDATA structure. //============================================================================== assert( pBase ); //============================================================================== // Optimize by not doing it over again. //============================================================================== if (pBase != m_pLastBindBase) { hr = E_UNEXPECTED; m_pLastBindBase = 0; for (icol=0; icol < m_cTotalCols; icol++) { //====================================================================== // Parent columns... what about nested ? //====================================================================== pColumn = (COLUMNDATA *) (pBase + m_Columns.GetDataOffset(icol)); hr = m_pRowData->SetColumnBind( icol, pColumn ); if( hr != S_OK ) { break; } } if( hr == S_OK ) { //================================================= // Remember in case we bind to same place again. //================================================= m_pLastBindBase = pBase; } } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // Shorthand way to get the address of a row buffer. Later we may extend this so that it can span several // non-contiguous blocks of memory. // // Pointer to the buffer. // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ROWBUFF* CRowset::GetRowBuff( HROW iRow, // IN Row to get address of. BOOL fDataLocation ) // IN Get the Data offset. { HSLOT hSlot = -1; //===================================================================== // This assumes iRow is valid... //===================================================================== assert( m_rgbRowData ); assert( m_cbRowSize ); assert( iRow > 0 ); if(m_bIsChildRs == FALSE) { //================================================= // Get the slot number for the row //================================================= hSlot = m_InstMgr->GetSlot(iRow); } //================================================================================= // if rowset is refering to qualifiers then add the row to the particular chapter //================================================================================= else { //================================================= // Get the slot number for the row //================================================= hSlot = m_pChapterMgr->GetSlot(iRow); } return (hSlot != -1) ? GetRowBuffer(m_pIBuffer,(ULONG)hSlot): NULL; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// // // // Shorthand way to get the address of a row buffer. // // Pointer to the buffer. // ///////////////////////////////////////////////////////////////////////////////////////////////////////////// ROWBUFF* CRowset::GetRowBuffFromSlot( HSLOT hSlot, // IN Row to get address of. BOOL fDataLocation ) // IN Get the Data offset. { //===================================================================== // This assumes iRow is valid... //===================================================================== assert( m_rgbRowData ); assert( m_cbRowSize ); assert( hSlot >= 0 ); return GetRowBuffer(m_pIBuffer,hSlot); } //////////////////////////////////////////////////////////////////////////// // Reset the position of the instances in the enumerator to the begining //////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ResetInstances() { return m_pMap->ResetInstances(); } //////////////////////////////////////////////////////////////////////////// // Reset the qualifer set of the property/class/instance //////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ResetQualifers(HCHAPTER hChapter) { HRESULT hr = S_OK; CWbemClassWrapper *pInst = NULL; //===================================================================== // Get the pointer to instance for which qualifier is to // be reset //===================================================================== if( hChapter > 0 && m_bIsChildRs == TRUE) { pInst = m_pChapterMgr->GetInstance(hChapter); } else { pInst = m_pInstance; } //================================================= // If valid instance then reset the qualifier //================================================= if(pInst) { m_pMap->ReleaseQualifier(pInst,m_strPropertyName); } else { hr = DB_E_BADCHAPTER; } return hr; } ///////////////////////////////////////////////////////////////////////////////// // Reset the position of the instances in the enumerator the required position ///////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ResetRowsetToNewPosition(DBROWOFFSET uWhich,CWbemClassWrapper *pInst) { HRESULT hr = S_OK; switch(m_uRsType) { case PROPERTYQUALIFIER: hr = m_pMap->ResetPropQualiferToNewPosition(pInst,uWhich,m_strPropertyName); break; case CLASSQUALIFIER: hr = m_pMap->ResetClassQualiferToNewPosition(pInst,uWhich); break; case SCHEMA_ROWSET: // NTRaid : 134987 // 07/12/00 hr = m_pMap->ResetInstancesToNewPosition(uWhich); break; case 0: case COMMAND_ROWSET: case METHOD_ROWSET: hr = m_pMap->ResetInstancesToNewPosition(uWhich); break; default: hr = E_FAIL; break; } return hr; } /////////////////////////////////////////////////////// // Get the pointer and key to the next instance /////////////////////////////////////////////////////// HRESULT CRowset::GetNextInstance(CWbemClassWrapper *&ppInst,CBSTR &strKey, BOOL bFetchBack) { //================================================= // Reset the column Index of the data manager //================================================= m_pRowData->ResetColumns(); return m_pMap->GetNextInstance(ppInst,strKey,bFetchBack); } /////////////////////////////////////////////////////// // Get the next property qualifier /////////////////////////////////////////////////////// HRESULT CRowset::GetNextPropertyQualifier(CWbemClassWrapper *pInst,BSTR strPropName,BSTR &strQualifier,BOOL bFetchBack) { HRESULT hr = S_OK; //================================================= // Reset the column Index of the data manager //================================================= m_pRowData->ResetColumns(); hr = m_pMap->GetNextPropertyQualifier(pInst,strPropName,strQualifier,bFetchBack); return hr; } /////////////////////////////////////////////////////// // Get the next Class qualifier /////////////////////////////////////////////////////// HRESULT CRowset::GetNextClassQualifier(CWbemClassWrapper *pInst,BSTR &strQualifier,BOOL bFetchBack) { HRESULT hr = S_OK; //================================================= // Reset the column Index of the data manager //================================================= m_pRowData->ResetColumns(); hr = m_pMap->GetNextClassQualifier(pInst,strQualifier,bFetchBack); return hr; } ////////////////////////////////////////////////////////////////////////// // Get the data from the instance and populate it into the local buffer ////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GetInstanceDataToLocalBuffer(CWbemClassWrapper *pInst,HSLOT hSlot,BSTR strQualifier) { HRESULT hr = S_OK; PROWBUFF pRowBuff = NULL; pRowBuff = GetRowBuffFromSlot( hSlot, TRUE ); if (FAILED( Rebind((BYTE *)pRowBuff ))) { hr = E_FAIL ; } else //===================================================== // Reset the column to point to the first column and // get the data and put it into the buffer //===================================================== if( S_OK == (hr = m_pRowData->ResetColumns())) { switch(m_uRsType) { case PROPERTYQUALIFIER: hr = m_pMap->GetDataForPropertyQualifier(m_pRowData,pInst,m_strPropertyName,strQualifier,&m_Columns); break; case CLASSQUALIFIER: hr = m_pMap->GetDataForClassQualifier(m_pRowData,pInst,strQualifier,&m_Columns); break; case SCHEMA_ROWSET: hr = m_pMap->GetDataForSchemaInstance(m_pRowData,pInst,&m_Columns); break; case 0: case COMMAND_ROWSET: case METHOD_ROWSET: hr = m_pMap->GetDataForInstance(m_pRowData,pInst,&m_Columns); break; default: hr = E_FAIL; break; } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Set rowset properties. This is called during initialization of the rowset /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::SetRowsetProperties(const ULONG cPropertySets, const DBPROPSET rgPropertySets[] ) { HRESULT hr = S_OK; VARIANT varPropVal; VariantInit(&varPropVal); LONG lFlag = 0; // call the base class implementation for setting properties hr = SetProperties(cPropertySets,rgPropertySets); //============================================================================ // call this function to set the DBPROP_UPDATIBILITY to readonly if the Datasource // open mode is readonly //============================================================================ if( (hr == S_OK) || (hr == DB_S_ERRORSOCCURRED) ) { SynchronizeDataSourceMode(); } //============================================================================ // Get some properties to determine whether to support bookmarks or not //============================================================================ if( S_OK == GetRowsetProperty(DBPROP_CANSCROLLBACKWARDS,varPropVal) && varPropVal.vt == VT_BOOL && varPropVal.boolVal == VARIANT_TRUE) { lFlag = lFlag | CANSCROLLBACKWARDS; } if( S_OK == GetRowsetProperty(DBPROP_CANFETCHBACKWARDS,varPropVal) && varPropVal.vt == VT_BOOL && varPropVal.boolVal == VARIANT_TRUE) { lFlag = lFlag | CANFETCHBACKWARDS; } if( S_OK == GetRowsetProperty(DBPROP_IRowsetLocate,varPropVal) && varPropVal.vt == VT_BOOL && varPropVal.boolVal == VARIANT_TRUE) { lFlag = lFlag | IROWSETLOCATE; } if( S_OK == GetRowsetProperty(DBPROP_OTHERINSERT,varPropVal) && varPropVal.vt == VT_BOOL && varPropVal.boolVal == VARIANT_TRUE) { lFlag = lFlag | OTHERINSERT; } //============================================================================ // if bookmarks are asked then set the fetchback and scrollback properties to true //============================================================================ varPropVal.vt = VT_BOOL; if(IROWSETLOCATE & lFlag ) { varPropVal.boolVal = VARIANT_TRUE; SetRowsetProperty(DBPROP_CANFETCHBACKWARDS,varPropVal); SetRowsetProperty(DBPROP_CANSCROLLBACKWARDS,varPropVal); SetRowsetProperty(DBPROP_BOOKMARKS,varPropVal); lFlag = lFlag | CANSCROLLBACKWARDS; lFlag = lFlag | CANFETCHBACKWARDS; lFlag = lFlag | BOOKMARKPROP; } //============================================================================ // Bookmarks are not supported for qualifier rowsets //============================================================================ if(m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER) { varPropVal.boolVal = VARIANT_FALSE; SetRowsetProperty(DBPROP_BOOKMARKS,varPropVal); SetRowsetProperty(DBPROP_IRowsetLocate,varPropVal); lFlag = lFlag & ~BOOKMARKPROP; lFlag = lFlag & ~IROWSETLOCATE; } VariantClear(&varPropVal); return hr; } /////////////////////////////////////////////////////////////////////////// // Function to Allocate and Iniatialize rowsets for child recordsets // /////////////////////////////////////////////////////////////////////////// HRESULT CRowset::AllocateAndInitializeChildRowsets() { HRESULT hr = E_FAIL; DBPROPSET *rgPropsets = NULL; ULONG cProperties = 0; ULONG nIndex = 0 , nIndex2 = 0; ULONG lColType = 0; //=========================================================================================== // if there are nested columns in the rowset and if childrowsets are not already allocated //=========================================================================================== if(m_cNestedCols > 0 && m_ppChildRowsets == NULL) { //============================================================= // Allocate pointers for the child rowsets //============================================================= m_ppChildRowsets = (CBaseRowObj **)new CRowset*[m_cTotalCols]; if(m_ppChildRowsets == NULL) { hr = E_OUTOFMEMORY; } else { //================================================================================ // Get the rowset Properties //================================================================================ if(S_OK == (hr = m_pIRowsetInfo->GetProperties(cProperties,NULL,&cProperties,&rgPropsets))) { for ( nIndex = 0 ; nIndex < m_cTotalCols ; nIndex++) { //======================================================================== // if the columntype is of CHAPTER then allocate a rowset and initialize //======================================================================== if(m_Columns.ColumnFlags(nIndex) & DBCOLUMNFLAGS_ISCHAPTER ) { lColType = m_pMap->ParseQualifiedNameToGetColumnType(m_Columns.ColumnName(nIndex)); if(lColType == WMI_CLASS_QUALIFIER) { m_ppChildRowsets[nIndex] = (CBaseRowObj*) new CRowset(m_pUnkOuter,CLASSQUALIFIER, NULL,m_pCreator, m_pMap); } else if(lColType == WMI_PROPERTY_QUALIFIER) { m_ppChildRowsets[nIndex] = (CBaseRowObj*) new CRowset(m_pUnkOuter,PROPERTYQUALIFIER, m_Columns.ColumnName(nIndex-1),m_pCreator, m_pMap); } if(m_ppChildRowsets[nIndex] == NULL) { hr = E_OUTOFMEMORY; break; } else { //=================================================================== // Initialize the rowset properties //=================================================================== hr = ((CRowset *)m_ppChildRowsets[nIndex])->InitRowset( cProperties, rgPropsets ); m_ppChildRowsets[nIndex]->AddRef(); } } // if for columntype else m_ppChildRowsets[nIndex] = NULL; } // for } // GetProperties //========================================================================== // Free memory we allocated to by m_pIRowsetInfo->GetProperties //========================================================================== m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cProperties, rgPropsets); } // if memory for pointers allocated successfully } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get the pointer to the child recordset for the given ordinal /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GetChildRowset(DBORDINAL ulOrdinal,REFIID riid, IUnknown ** ppIRowset) { HRESULT hr = S_OK; //=============================================================================================== // If row the child rowset pointer is fetched before fetching any rows from the parent rowsets // then this will be called before allocating the child recordset. SO allocate the child rowsets //=============================================================================================== if( m_ppChildRowsets == NULL) { hr = AllocateAndInitializeChildRowsets(); } if(SUCCEEDED(hr)) { hr = DB_E_NOTAREFERENCECOLUMN; if(m_cNestedCols > 0) { if( ulOrdinal > m_cTotalCols) { hr = DB_E_BADORDINAL; } else if(m_ppChildRowsets[ulOrdinal] != NULL) { hr = m_ppChildRowsets[ulOrdinal]->QueryInterface(riid,(void **)ppIRowset); } } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Check if the HCHAPTER passed is valid or not /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::CheckAndInitializeChapter(HCHAPTER hChapter) { HRESULT hr = E_FAIL; if(m_bIsChildRs && m_pChapterMgr->IsExists(hChapter)) { hr = S_OK; } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to release the instance pointers when ReleaseRows is called /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ReleaseInstancePointer(HROW hRow) { //======================================================================== // if the recordset is representing a class //======================================================================== if(m_bIsChildRs == FALSE ) { m_InstMgr->DeleteInstanceFromList(hRow); } //=============================================================================== // if the row is a child recordset then delete the row from the chapter manager //=============================================================================== if(m_bIsChildRs == TRUE) { m_pChapterMgr->DeleteHRow(hRow); } return S_OK; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to check if the row exist in the chapter or instance manager /////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CRowset::IsRowExists(HROW hRow) { BOOL bRet = FALSE; if( hRow > 0) { //======================================================================== // if the recordset is representing a class //======================================================================== if(m_bIsChildRs == FALSE) { bRet = m_InstMgr->IsRowExists(hRow); } //=============================================================================== // if the row is a child recordset then delete the row from the chapter manager //=============================================================================== if(m_bIsChildRs == TRUE) { bRet = m_pChapterMgr->IsRowExists(hRow); } } return bRet; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to release all the open rows // This is called from the destructor /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ReleaseAllRows() { DBROWOPTIONS rgRowOptions[1]; DBREFCOUNT rgRefCounts[1]; DBROWSTATUS rgRowStatus[1]; HRESULT hr = S_OK; //========================================================== // if there are any rows fetched //========================================================== if(!( ( m_bIsChildRs == TRUE && m_pChapterMgr == NULL) || ( m_bIsChildRs == FALSE && m_InstMgr == NULL))) { memset(rgRowOptions,0,sizeof(DBROWOPTIONS)); memset(rgRowStatus,0,sizeof(DBROWSTATUS)); rgRefCounts[0] = 0; DBCOUNTITEM cRows = 0 , nIndex = 0; HROW *prghRows = NULL; //================================================= // if the rowset is child rowset get the list // open rowset from the chapter manager //================================================= if(m_bIsChildRs) { hr = m_pChapterMgr->GetAllHROWs(prghRows,cRows); } //========================================= // else get it from the instance manager //========================================= else { hr = m_InstMgr->GetAllHROWs(prghRows,cRows); } //=============================================== // If there are open rows the release the rows //=============================================== if(cRows > 0) { for(nIndex = 0 ; nIndex < cRows ; nIndex++) { //============================================================== // Release till the reference count on the row goes to zero // and thus all the resources allocated for the is released //============================================================== do { hr = m_pIRowset->ReleaseRows(1, &(prghRows[nIndex]),rgRowOptions,rgRefCounts,NULL); }while(rgRefCounts[0] > 0 && hr == S_OK); } //==================================================================================== // delete the memory allocated by the functions which gives the list of open rows //==================================================================================== if(prghRows != NULL) { delete [] prghRows; prghRows = NULL; } } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to find whether the slot for the particular row is set /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::IsSlotSet(HSLOT hRow) { HSLOT hSlot = -1; HRESULT hr = E_FAIL; hSlot = GetSlotForRow(hRow); // If valid slot if( (hSlot) >= 0) { hr = m_pIAccessor->GetBitArrayPtr()->IsSlotSet(hSlot); } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to return the slot number of the row /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HSLOT CRowset::GetSlotForRow(HROW hRow ) // IN Row handle for which slot number is required { HSLOT hSlot = -1; //================================================================= // if the rowset is a parent rowset then // get slot number from the instance manager else get it // from the chapter manager //================================================================= if(m_bIsChildRs == FALSE) { //================================================= // Get the slot for the row //================================================= hSlot = m_InstMgr->GetSlot(hRow); } //================================================================================= // if rowset is refering to qualifiers then add the row to the particular chapter //================================================================================= else { //================================================= // Get the slot for the row //================================================= hSlot = m_pChapterMgr->GetSlot(hRow); } return hSlot; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function which fetches data and puts it into the local buffer // NTRaid: 145773 // 07/18/00 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GetData(HROW hRow,BSTR strQualifier ) { CWbemClassWrapper * pInst = NULL; BSTR strKey; HSLOT hSlot = 0; HRESULT hr = S_OK; PROWBUFF pRowBuff = NULL; CVARIANT varKey; HCHAPTER hChapter = 0; //=================================================================== /// get the instance pointer corresponding to the HROW passed // if rowset is referiing to a class and not to qualifiers then //=================================================================== if(m_bIsChildRs == FALSE) { pInst = m_InstMgr->GetInstance(hRow); m_InstMgr->GetInstanceKey(hRow,&strKey); hSlot = m_InstMgr->GetSlot(hRow); } //=================================================================== // if the recordset is a child rs and representing a qualifier //=================================================================== else { hChapter = m_pChapterMgr->GetChapterForHRow(hRow); if( hChapter <= 0) { hr = DB_E_BADCHAPTER; } else { //=================================================================== // get the instance pointer corresponding to the //=================================================================== pInst = m_pChapterMgr->GetInstance(hChapter); m_pChapterMgr->GetInstanceKey(hChapter,&strKey, hRow); hSlot = m_pChapterMgr->GetSlot(hRow); } } // NTRaid:111830 if(hSlot == 0 || pInst == NULL) { hr = DB_E_BADROWHANDLE; } else if ( SUCCEEDED(hr)) { if(!( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER)) { assert(strQualifier == NULL); //=================================================================== // Refresh the instance. // This is to get the latest instance if modified from another instance //=================================================================== if(m_ulProps & OTHERUPDATEDELETE) { hr = RefreshInstance(pInst); } //=================================================================== // Filling data for the bookmark column //=================================================================== varKey.SetStr(strKey); } else { // If the otherupdate is true then strQualifier will be NULL if(m_ulProps & OTHERUPDATEDELETE) { // Filling data for the bookmark column varKey.SetStr(strKey); } else { // Filling data for the bookmark column varKey.SetStr(strQualifier); } } if(SUCCEEDED(hr = GetInstanceDataToLocalBuffer(pInst,hSlot,varKey.GetStr()))) { //=========================================================================== // if there is atleast one row retrieved and there are neseted columns // then allocate rows for the child recordsets //=========================================================================== if(m_cNestedCols > 0 ) { if(m_ppChildRowsets == NULL) { hr = AllocateAndInitializeChildRowsets(); } //===================================================================== // Fill the HCHAPTERS for the column //===================================================================== if( SUCCEEDED(hr)) { hr = FillHChaptersForRow(pInst,strKey); } } if( SUCCEEDED(hr)) { //=================================================== // if the class is not representing qualilfiers //=================================================== if(m_bIsChildRs == FALSE) { //================================================= // Set the slot for the row //================================================= hr = m_InstMgr->SetSlot(hRow,hSlot); } //================================================================================= // if rowset is refering to qualifiers then add the row to the particular chapter //================================================================================= else { //============================================== // Set the slot for the Row //============================================== if(SUCCEEDED(hr = m_pChapterMgr->SetSlot(hRow,hSlot))) { m_pChapterMgr->SetInstance(hChapter,pInst, varKey.GetStr() ,hRow); } } if(SUCCEEDED(hr)) { pRowBuff = GetRowBuff( (ULONG) hRow, TRUE ); // NTRaid:111830 // 06/07/00 if(pRowBuff) { //======================================== // Increment the reference count //======================================== pRowBuff->ulRefCount++; } else { hr = E_FAIL; } } //============================================== // Free the string //============================================== if(m_bIsChildRs == FALSE) { SysFreeString(strKey); } } // Succeeded(hr) } varKey.Clear(); } // Succeeded(hr) return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to update a row to WMI // NTRaid : 143868 // 07/15/00 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::UpdateRowData(HROW hRow,PACCESSOR pAccessor , BOOL bNewInst) { HRESULT hr = S_OK; PROWBUFF pRowBuff = NULL; DBORDINAL ibind = 0; COLUMNDATA * pColumnData = NULL; CWbemClassWrapper * pInst = NULL; DBORDINAL icol = 0; BOOL bRowModified = FALSE; BSTR bstrColName; BSTR strQualifierName =Wmioledb_SysAllocString(NULL); CDataMap dataMap; VARIANT varData; LONG lFlavor = 0; VariantInit(&varData); DWORD dwCIMType = 0; //================================================================================= // get the pointer to the instance //================================================================================= if(m_bIsChildRs == FALSE) { if( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { pInst = m_pInstance; } else if( m_uRsType != COLUMNSROWSET && m_uRsType != SCHEMA_ROWSET && m_uRsType != METHOD_ROWSET) { pInst = m_InstMgr->GetInstance(hRow); } } else { pInst = m_pChapterMgr->GetInstance(m_pChapterMgr->GetChapterForHRow(hRow)); } //================================================================================= // Get the pointer to the row data //================================================================================= pRowBuff = GetRowBuff((ULONG) hRow, TRUE ); // NTRaid:111823-111825 // 06/07/00 // If the row is not an instance or qualifier if(pInst == NULL) { hr = DB_E_NOTSUPPORTED; } else //================================================================================= // IF the rowset is a qualifier type rowset //================================================================================= if( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { //================================================================================= // get the qualifier name //================================================================================= pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERNAMECOL)); if( pColumnData->pbData == NULL) { hr = DB_E_INTEGRITYVIOLATION; // This is because one of the column values expected // is NULL or EMPTY bRowModified = TRUE; } else { strQualifierName = Wmioledb_SysAllocString((WCHAR *)pColumnData->pbData); //================================================================================= // Get the qualifier Value //================================================================================= pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERVALCOL)); VariantCopy(&varData,(VARIANT *)pColumnData->pbData); //================================================================================= // Get the qualifier flavor //================================================================================= pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERFLAVOR)); lFlavor = pColumnData->pbData !=NULL ? *(LONG *)pColumnData->pbData : 0 ; if( varData.vt != VT_EMPTY || varData.vt != VT_NULL) { //================================================================================= // Set the qualifier //================================================================================= hr = m_pMap->SetQualifier(pInst,m_strPropertyName,strQualifierName,&varData,lFlavor); if( SUCCEEDED(hr)) { //================================================================================= // This is becuase , we are just adding a qualifier not a new instance //================================================================================= bNewInst = FALSE; bRowModified = TRUE; } } else { //================================================================================= // This is because one of the column values expected is NULL or empty //================================================================================= hr = DB_E_INTEGRITYVIOLATION; bRowModified = TRUE; } SysFreeString(strQualifierName); VariantClear(&varData); } } else for (ibind = 0; ibind < (int)pAccessor->cBindings; ibind++) { icol = pAccessor->rgBindings[ibind].iOrdinal; pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(icol)); //================================================================================= // If the columndata is modified then //================================================================================= if(pColumnData->dwStatus & COLUMNSTAT_MODIFIED) { bstrColName = Wmioledb_SysAllocString((OLECHAR *)m_Columns.ColumnName(icol)); // this variable gets value only if the CIMTYPE is array dwCIMType = -1; // if the type is array , then get the original CIMTYPE as array type will // be given out as VT_ARRAY | VT_VARIANT if(pColumnData->dwType & DBTYPE_ARRAY) { dwCIMType = m_Columns.GetCIMType(icol); } if( pColumnData->pbData == NULL) { varData.vt = VT_NULL; } else { //================================================================================= // Call this function to convert the data to the appropriate datatype in a variant //================================================================================= dataMap.MapAndConvertOLEDBTypeToCIMType((USHORT)pColumnData->dwType,pColumnData->pbData,pColumnData->dwLength,varData,dwCIMType); } if( m_uRsType == 0) { //================================================================================= // Update the property //================================================================================= hr = m_pMap->SetProperty(pInst,bstrColName,&varData); } pColumnData->dwStatus &= ~COLUMNSTAT_MODIFIED; VariantClear(&varData); SysFreeString(bstrColName); bRowModified = TRUE; } } if(SUCCEEDED(hr) && (bRowModified == TRUE || bNewInst == TRUE)) { hr = m_pMap->UpdateInstance(pInst , bNewInst); } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to update a row to WMI // this is called from Row Object // NTRaid : 143868 // 07/15/00 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::UpdateRowData(HROW hRow,DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[ ]) { HRESULT hr = S_OK; PROWBUFF pRowBuff = NULL; DBORDINAL lIndex = 0; COLUMNDATA * pColumnData = NULL; CWbemClassWrapper * pInst = NULL; DBORDINAL icol = 0; BSTR bstrColName; CDataMap dataMap; VARIANT varData; VariantInit(&varData); LONG lFlavor = 0; BSTR strQualifierName =Wmioledb_SysAllocString(NULL); DWORD dwCIMType = 0; // get the pointer to the instance if(m_bIsChildRs == FALSE) { if( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { pInst = m_pInstance; } else if( m_uRsType != COLUMNSROWSET && m_uRsType != SCHEMA_ROWSET && m_uRsType != METHOD_ROWSET) { pInst = m_InstMgr->GetInstance(hRow); } } else { pInst = m_pChapterMgr->GetInstance(m_pChapterMgr->GetChapterForHRow(hRow)); } //========================================= // Get the pointer to the row data //========================================= pRowBuff = GetRowBuff((ULONG) hRow, TRUE ); // NTRaid:111823-111825 // 06/07/00 // If the row is not an instance or qualifier if(pInst == NULL) { hr = DB_E_NOTSUPPORTED; } else //================================================ // IF the rowset is a qualifier type rowset //================================================ if( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { icol = GetOrdinalFromColName(rgColumns[lIndex].columnid.uName.pwszName); //=============================================== // Only qualifier value can be modified //=============================================== if(cColumns == 1 && icol == QUALIFIERVALCOL) { //=============================================== // get the qualifier name //=============================================== pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERNAMECOL)); if( pColumnData->pbData == NULL) { hr = DB_E_INTEGRITYVIOLATION; // This is because one of the column values expected // is NULL or EMPTY } else { strQualifierName = Wmioledb_SysAllocString((WCHAR *)pColumnData->pbData); //=============================================== // Get the qualifier Value //=============================================== pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERVALCOL)); VariantCopy(&varData,(VARIANT *)pColumnData->pbData); //=============================================== // Get the qualifier flavor //=============================================== pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERFLAVOR)); lFlavor = pColumnData->pbData !=NULL ? *(LONG *)pColumnData->pbData : 0 ; if( varData.vt != VT_EMPTY || varData.vt != VT_NULL) { //=============================================== // Set the qualifier //=============================================== hr = m_pMap->SetQualifier(pInst,m_strPropertyName,strQualifierName,&varData,lFlavor); } else { //======================================================== // This is because one of the column values expected //is NULL or EMPTY //======================================================== hr = DB_E_INTEGRITYVIOLATION; } SysFreeString(strQualifierName); VariantClear(&varData); } } else { //==================================================== // Only qualifier value can be modified //==================================================== hr = E_FAIL; } } else for (lIndex = 0; lIndex < cColumns; lIndex++) { icol = GetOrdinalFromColName(rgColumns[lIndex].columnid.uName.pwszName); //============================================================================= // If the column is not present in the rowset it is already updated in the // row. This will happen only when this method is called from the row object //============================================================================= if( (DB_LORDINAL)icol < 0) { continue; } pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(icol)); //============================================================================= // If the columndata is modified then //============================================================================= if(pColumnData->dwStatus & COLUMNSTAT_MODIFIED) { bstrColName = Wmioledb_SysAllocString((OLECHAR *)m_Columns.ColumnName(icol)); dwCIMType = -1; //=================================================================================== // if the type is array , then get the original CIMTYPE as array type will // be given out as VT_ARRAY | VT_VARIANT //=================================================================================== if(pColumnData->dwType & DBTYPE_ARRAY) { dwCIMType = m_Columns.GetCIMType(icol); } if( pColumnData->pbData == NULL) { varData.vt = VT_NULL; } else { //=================================================================================== // Call this function to convert the data to the appropriate datatype in a variant //=================================================================================== dataMap.MapAndConvertOLEDBTypeToCIMType((USHORT)pColumnData->dwType,pColumnData->pbData,pColumnData->dwLength,varData,dwCIMType); } //================================ // Update the property //================================ if( m_uRsType == 0) { //================================== // Update the property //================================== hr = m_pMap->SetProperty(pInst,bstrColName,&varData); } pColumnData->dwStatus &= ~COLUMNSTAT_MODIFIED; VariantClear(&varData); SysFreeString(bstrColName); } } //============================================================================= // If everything is fine then update the instance //============================================================================= if( hr == S_OK) { hr = m_pMap->UpdateInstance(pInst , FALSE); } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to delete a instance(Row) from WMI // NTRaid : 143524 // 07/15/00 /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::DeleteRow(HROW hRow,DBROWSTATUS * pRowStatus) { HRESULT hr = S_OK; DBROWOPTIONS rgRowOptions[1]; ULONG rgRefCounts[1]; DBROWSTATUS rgRowStatus[1]; CWbemClassWrapper *pInst = NULL; VARIANT varProp; PROWBUFF pRowBuff = NULL; COLUMNDATA * pColumnData = NULL; VariantInit(&varProp); memset(rgRowOptions,0,sizeof(DBROWOPTIONS)); memset(rgRowStatus,0,sizeof(DBROWSTATUS)); rgRefCounts[0] = 0; if(pRowStatus != NULL) *pRowStatus = DBROWSTATUS_S_OK; //=================================================================== /// get the instance pointer corresponding to the HROW passed // if rowset is referiing to a class and not to qualifiers then //=================================================================== if(m_bIsChildRs == FALSE) { if( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { pInst = m_pInstance; } else if( m_uRsType != COLUMNSROWSET && m_uRsType != SCHEMA_ROWSET && m_uRsType != METHOD_ROWSET) { pInst = m_InstMgr->GetInstance(hRow); } } //=================================================================== // if the recordset is a child rs and representing a qualifier //=================================================================== else { //=================================================================== // get the instance pointer corresponding to the //=================================================================== pInst = m_pChapterMgr->GetInstance(m_pChapterMgr->GetChapterForHRow(hRow)); } // NTRaid:111800 // 06/07/00 // If the row is not an instance or qualifier if(pInst == NULL) { hr = DB_E_NOTSUPPORTED; } else // NTRaid : 143425 // 07/17/00 if( m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { // Delete qualifier //========================================= // Get the pointer to the row data //========================================= pRowBuff = GetRowBuff(hRow, TRUE ); //============================================= // Get the Data for the qualifier name //============================================= pColumnData = (COLUMNDATA *) (((BYTE *)pRowBuff )+ m_Columns.GetDataOffset(QUALIFIERNAMECOL)); //================================================================================ // This will always of type VT_BSTR as this column represents the QUALIFER name //================================================================================ if(pColumnData->dwType == VT_BSTR) { hr = m_pMap->DeleteQualifier(pInst,(BSTR)pColumnData->pbData,(m_uRsType == CLASSQUALIFIER),m_strPropertyName); } } else if( m_uRsType != COLUMNSROWSET && m_uRsType != SCHEMA_ROWSET && m_uRsType != METHOD_ROWSET) { //=================================== // Delete the Instance //=================================== hr = m_pMap->DeleteInstance(pInst); } else { hr = WBEM_E_PROVIDER_NOT_CAPABLE; } //=================================================================== // If delete is not allowed if it is not capable of deletion then // set the updatibility property of the rowset //=================================================================== if( hr == WBEM_E_PROVIDER_NOT_CAPABLE) { GetRowsetProperty(DBPROP_UPDATABILITY,varProp); varProp.lVal ^= DBPROPVAL_UP_DELETE; SetRowsetProperty(DBPROP_UPDATABILITY,varProp); hr = DB_E_NOTSUPPORTED; if(pRowStatus) { *pRowStatus = DBROWSTATUS_E_INTEGRITYVIOLATION; } } else if(FAILED(hr) && (pRowStatus != NULL)) { if(pRowStatus) { *pRowStatus = DBROWSTATUS_E_FAIL; } } if( hr == S_OK) { //==================================== // Set the row status to DELETED //==================================== SetRowStatus(hRow,DBROWSTATUS_E_DELETED); if(pRowStatus) { *pRowStatus = DBROWSTATUS_S_OK; } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Set the status of a row /////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CRowset::SetRowStatus(HROW hRow , DBSTATUS dwStatus) { if(m_bIsChildRs == FALSE) { m_InstMgr->SetRowStatus(hRow , dwStatus); } else { m_pChapterMgr->SetRowStatus(hRow , dwStatus); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Gets the current status of the row /////////////////////////////////////////////////////////////////////////////////////////////////////////////// DBSTATUS CRowset::GetRowStatus(HROW hRow ) { DBSTATUS dwStatus = DBROWSTATUS_E_FAIL; if(m_bIsChildRs == FALSE) { dwStatus = m_InstMgr->GetRowStatus(hRow); } else { dwStatus = m_pChapterMgr->GetRowStatus(hRow); } return dwStatus; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Gets Key value of a instance /////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CRowset::GetInstanceKey(HROW hRow , BSTR *strKey) { CWbemClassWrapper *pInst = NULL; //==================================== // get the pointer to the instance //==================================== if(m_bIsChildRs == FALSE) { pInst = m_InstMgr->GetInstance(hRow); m_InstMgr->GetInstanceKey(hRow,strKey); } else { pInst = m_pChapterMgr->GetInstance(m_pChapterMgr->GetChapterForHRow(hRow)); m_pChapterMgr->GetInstanceKey(hRow,strKey); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Set the status of a rowset or a chapter /////////////////////////////////////////////////////////////////////////////////////////////////////////////// void CRowset::SetStatus(HCHAPTER hChapter , DWORD dwStatus) { if(m_bIsChildRs == FALSE) { //================================ // skip caused END_OF_ROWSET //================================ m_dwStatus |= dwStatus; } else { //======================================================================== // set the status of the chapter to end of rowset //======================================================================== m_pChapterMgr->SetChapterStatus(hChapter , dwStatus); } } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Gets the status of a rowset or a chapter /////////////////////////////////////////////////////////////////////////////////////////////////////////////// DBSTATUS CRowset::GetStatus(HCHAPTER hChapter) { DBSTATUS dwStatus = 0; if(m_bIsChildRs == FALSE) { //================================ // skip caused END_OF_ROWSET //================================ dwStatus = m_dwStatus; } else { //======================================================================== // set the status of the chapter to end of rowset //======================================================================== dwStatus = m_pChapterMgr->GetChapterStatus(hChapter ); } return dwStatus; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Adds a new instance to the class /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::InsertNewRow(CWbemClassWrapper **ppNewInst) { HRESULT hr = S_OK; switch(m_uRsType) { case PROPERTYQUALIFIER: break; case CLASSQUALIFIER: break; case SCHEMA_ROWSET: hr = DB_E_NOTSUPPORTED; break; case 0: hr = m_pMap->AddNewInstance(ppNewInst); break; default: hr = E_FAIL; } return hr; } /////////////////////////////////////////////////////////////////////////////////////// // Function which releases the rowdata ( does not release the row) // release the memory allocated for the row and also the slot allocated for the row /////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ReleaseRowData(HROW hRow,BOOL bReleaseSlot) { HSLOT hSlot = 0; HRESULT hr = S_OK; //=================================================================== /// get the handle to slot //=================================================================== if(m_bIsChildRs == FALSE) { //=================================================================== // get the handle to slot for the instance //=================================================================== hSlot = m_InstMgr->GetSlot(hRow); if(bReleaseSlot) { // Reset the HSLOT in the chapter Manager m_InstMgr->SetSlot(hRow , -1); } } //=================================================================== // if the recordset is a child rs and representing a qualifier //=================================================================== else { //=================================================================== // get the handle to slot for the instance //=================================================================== hSlot = m_pChapterMgr->GetSlot(hRow); //================================================ // Reset the HSLOT in the chapter Manager //================================================ if(bReleaseSlot) { m_pChapterMgr->SetSlot(hRow ,-1); } } if( hSlot > 0) { if (FAILED( Rebind((BYTE *) GetRowBuffFromSlot( hSlot, TRUE )))) { hr = E_FAIL ; } else { //=========================================================== // release the memory allocated for the different columns //=========================================================== m_pRowData->ReleaseRowData(); //============================== // release the slots //============================== if(bReleaseSlot) { ReleaseSlots( m_pIBuffer, hSlot, 1 ); } } } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // Virtual Overidden function which is called from IColumnInfo to get the column information ///////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GetColumnInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo,WCHAR** ppStringsBuffer) { ULONG icol = 0; DBCOLUMNINFO* rgdbcolinfo = NULL; WCHAR* pstrBuffer = NULL; WCHAR* pstrBufferForColInfo = NULL; HRESULT hr = S_OK; DBCOUNTITEM nTotalCols = m_cTotalCols; BOOL bFlag = TRUE; if(!(m_ulProps & BOOKMARKPROP)) { nTotalCols--; bFlag = FALSE; } //======================================= // Copy the columninformation //======================================= if(SUCCEEDED(hr = m_Columns.CopyColumnInfoList(rgdbcolinfo,bFlag))) { //=========================================== // Copy the heap for column names. //=========================================== if ( m_Columns.ColumnNameListStartingPoint() != NULL){ ptrdiff_t dp; hr = m_Columns.CopyColumnNamesList(pstrBuffer); dp = (LONG_PTR) pstrBuffer - (LONG_PTR) (m_Columns.ColumnNameListStartingPoint()); dp >>= 1; //=========================================== // Loop through columns and adjust pointers // to column names. //=========================================== for ( icol =0; icol < nTotalCols; icol++ ) { if ( rgdbcolinfo[icol].pwszName ) { rgdbcolinfo[icol].pwszName += dp; } } } //============================== // Set the output parameters //============================== *prgInfo = &rgdbcolinfo[0]; *ppStringsBuffer = pstrBuffer; *pcColumns = nTotalCols; } return hr; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // get the instance pointer of a particular row ///////////////////////////////////////////////////////////////////////////////////////////////////////// CWbemClassWrapper *CRowset::GetInstancePtr(HROW hRow) { CWbemClassWrapper *pInst = NULL; if(m_bIsChildRs == FALSE) { pInst = m_InstMgr->GetInstance(hRow); } else { pInst = m_pChapterMgr->GetInstance(m_pChapterMgr->GetChapterForHRow(hRow)); } return pInst; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // Get the qualifier name which will be present in the first column for // qualifier rowset ///////////////////////////////////////////////////////////////////////////////////////////////////////// void CRowset::GetQualiferName(HROW hRow,BSTR &strBookMark) { PROWBUFF pRowBuff = NULL; PCOLUMNDATA pColumnData = NULL; pRowBuff = GetRowBuff( (ULONG) hRow, TRUE ); pColumnData = (COLUMNDATA *) ((BYTE *) pRowBuff + m_Columns.GetDataOffset(0)); //=================================================================== // FIXXX More work is to be done on this //=================================================================== if( pColumnData->dwType == DBTYPE_BSTR ) strBookMark = Wmioledb_SysAllocString((WCHAR *)(pColumnData->pbData)); } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Generate a new HCHAPTER for the current row and add it to the CHAPTER manager /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::FillHChaptersForRow(CWbemClassWrapper *pInst, BSTR strKey) { HRESULT hr = S_OK; ULONG nIndex = 0; PCOLUMNDATA * pColumnData = NULL; CVARIANT var; HCHAPTER hChapter = 0; //============================================================================ // if there are nested columns in the rowset //============================================================================ if(m_cNestedCols > 0) { for ( ULONG nIndex = 0 ; nIndex < m_cTotalCols ; nIndex++) { //============================================================================ // if the columntype is of CHAPTER then allocate a rowset and initialize //============================================================================ if(m_Columns.ColumnFlags(nIndex) & DBCOLUMNFLAGS_ISCHAPTER ) { hChapter = GetNextHChapter(); var.SetLONG((LONG)hChapter); if(FAILED(hr = m_pRowData->CommitColumnToRowData(var,nIndex,VT_UI4))) { break; } //============================================================================ // Add the chapter to the corresponding child recordset //============================================================================ m_ppChildRowsets[nIndex]->m_pChapterMgr->AddChapter(hChapter); m_ppChildRowsets[nIndex]->m_pChapterMgr->SetInstance(hChapter,pInst,strKey); } // if for columntype } // for } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to add reference to a chapter /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::AddRefChapter(HCHAPTER hChapter,DBREFCOUNT * pcRefCount) { HRESULT hr = E_UNEXPECTED; ULONG ulRet = -1; //=========================================== // if the rowset is a child rowset //=========================================== if(m_bIsChildRs == TRUE) { //======================================= // If chapter belongs to the rowset //======================================= if(m_pChapterMgr->IsExists(hChapter) == FALSE) { hr = DB_E_BADCHAPTER; } else { //=================================== // Add reference to the chapter //=================================== ulRet = m_pChapterMgr->AddRefChapter(hChapter); if( ulRet > 0) { hr = S_OK; } } } if(pcRefCount != NULL) { *pcRefCount = ulRet; } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Function to release reference to a chapter /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::ReleaseRefChapter(HCHAPTER hChapter , ULONG * pcRefCount) { HRESULT hr = E_UNEXPECTED; ULONG ulRet = -1; //======================================= // if the rowset is a child rowset //======================================= if(m_bIsChildRs == TRUE) { //=================================== // If chapter belongs to the rowset //=================================== if(m_pChapterMgr->IsExists(hChapter) == FALSE) { hr = DB_E_BADCHAPTER; } else { //====================================== // Release reference to the chapter //====================================== ulRet = m_pChapterMgr->ReleaseRefChapter(hChapter); if(((LONG)ulRet) >= 0) { hr = S_OK; } } } if(pcRefCount != NULL) { *pcRefCount = ulRet; } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get the number of rows in the rowset /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GetRowCount() { HRESULT hr = S_OK; switch(m_uRsType) { case PROPERTYQUALIFIER: m_lRowCount = -1; break; case CLASSQUALIFIER: m_lRowCount = -1; break; case SCHEMA_ROWSET: m_lRowCount = -1; break; case 0: case COMMAND_ROWSET: hr = m_pMap->GetInstanceCount(m_lRowCount); break; default: hr = E_FAIL; } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Get the Data to local buffer for a particular row /////////////////////////////////////////////////////////////////////////////////////////////////////////////// HRESULT CRowset::GetDataToLocalBuffer(HROW hRow) { HSLOT hSlot = 0; HRESULT hr = S_OK; BSTR strBookMark = Wmioledb_SysAllocString(NULL); if(m_uRsType == PROPERTYQUALIFIER || m_uRsType == CLASSQUALIFIER ) { GetQualiferName(hRow,strBookMark); } hSlot = GetSlotForRow(hRow); if (FAILED( Rebind((BYTE *) GetRowBuffFromSlot( hSlot, TRUE )))) { hr = E_FAIL; } else { //====================================== // Release the previous row data //====================================== m_pRowData->ReleaseRowData(); //====================================== // Get the data for the current row //====================================== if(SUCCEEDED(hr = GetData(hRow,strBookMark))) { m_ulLastFetchedRow = hRow; } if( strBookMark != NULL) { SysFreeString(strBookMark); } } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Check if a particular instance is deleted. // A particular instance is deleted , if it is deleted from WMI and appropriate properties are // set for different cursor types /////////////////////////////////////////////////////////////////////////////////////////////////////////////// BOOL CRowset::IsInstanceDeleted(CWbemClassWrapper *pInst) { DWORD dwStatus = m_pMap->GetInstanceStatus(pInst); BOOL bRet = FALSE; //=================================== // if the cursor is dynamic //=================================== if((m_ulProps & OTHERINSERT) && dwStatus != DBSTATUS_S_OK) { bRet = TRUE; } else if(((m_ulProps & OWNUPDATEDELETE) && dwStatus == DBROWSTATUS_E_DELETED) || ((m_ulProps & OTHERUPDATEDELETE) && dwStatus == DBSTATUS_E_UNAVAILABLE)) { bRet = TRUE; } return bRet; } void CRowset::SetCurFetchDirection(FETCHDIRECTION FetchDir) { m_FetchDir = FetchDir; m_pMap->SetCurFetchDirection(FetchDir); }