mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3124 lines
98 KiB
3124 lines
98 KiB
///////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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);
|
|
}
|