|
|
///////////////////////////////////////////////////////////////////////////////////
//
// 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); }
|