|
|
///////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMIOLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// CRow object implementation
//
//
///////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
#include "WmiOleDBMap.h"
#define PATHSEPARATOR L"/"
/////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor for this class
/////////////////////////////////////////////////////////////////////////////////////////////////
CRow::CRow(LPUNKNOWN pUnkOuter,CRowset *pRowset,PCDBSESSION pObj,CWbemConnectionWrapper *pCon ) : CBaseRowObj(pUnkOuter) { InitVars();
m_pMap = pRowset->GetWmiOleDBMap(); m_pMap->AddRef();
m_pUtilProp = pRowset->m_pUtilProp;
m_pCreator = pObj; m_pSourcesRowset = pRowset; m_pSourcesRowset->AddRef(); m_pCreator->GetOuterUnknown()->AddRef();
//===============================================
// Add this rowset ot list of open rowset
//===============================================
m_pCreator->AddRowset(this);
pRowset->QueryInterface(IID_IConvertType, (void **)&m_pIConvertType); m_pCon = pCon;
InterlockedIncrement(&g_cObj); }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Constructor for this class. This is called from the root binder object
/////////////////////////////////////////////////////////////////////////////////////////////////
CRow::CRow(LPUNKNOWN pUnkOuter, PCDBSESSION pObj ) : CBaseRowObj(pUnkOuter) { InitVars();
m_pCreator = pObj; m_pSourcesRowset = NULL; m_pCreator->GetOuterUnknown()->AddRef(); //===============================================
// Add this rowset ot list of open rowset
//===============================================
m_pCreator->AddRowset(this);
InterlockedIncrement(&g_cObj); }
void CRow::InitVars() { m_pMap = NULL;
m_pUtilProp = NULL;
m_pCreator = NULL; m_pSourcesRowset = NULL;
m_pRowData = NULL; m_pIBuffer = NULL;
m_strURL = NULL; m_strKey = NULL;
m_rgbRowData = NULL; m_pRowColumns = NULL;
m_pInstance = NULL;
m_pIColumnsInfo = NULL; m_pIRow = NULL; m_pIConvertType = NULL; m_pIGetSession = NULL; m_pIRowChange = NULL; m_pIScopedOperations = NULL;
m_cTotalCols = 0; m_cCols = 0; m_cNestedCols = 0; m_cRef = 0; m_cbRowSize = 0;
m_ulProps = 0; m_hRow = 0; m_dwStatus = 0;
m_bHelperFunctionCreated = FALSE; m_bClassChanged = FALSE;
m_rowType = ROW_INSTANCE;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// Destructor for this class
/////////////////////////////////////////////////////////////////////////////////////////////////
CRow::~CRow() {
if (NULL != m_pIBuffer){ ReleaseSlotList( m_pIBuffer ); }
//===============================================================
// NOTE: m_pMap releases the class ptr in destructor and if
// the reference count goes to 0 then this will released
//===============================================================
m_pMap->Release();
// If the row object is created from a rowset object then release all the interfaces
if(m_pSourcesRowset != NULL) { m_pIConvertType->Release(); m_pSourcesRowset->Release(); SAFE_DELETE_PTR(m_pRowColumns); } else { SAFE_DELETE_PTR( m_pIConvertType ); SAFE_DELETE_PTR( m_pUtilProp ); }
//===============================================================
// Free contained interfaces
//===============================================================
SAFE_DELETE_PTR( m_pIColumnsInfo ); SAFE_DELETE_PTR( m_pIRow ); SAFE_DELETE_PTR( m_pIGetSession ); SAFE_DELETE_PTR( m_pIRowChange ); SAFE_DELETE_PTR(m_pRowData); SAFE_DELETE_PTR(m_pIScopedOperations); SAFE_DELETE_PTR(m_pISupportErrorInfo); /*
if(m_pSourcesRowset == NULL) { SAFE_DELETE_PTR(m_pInstance); } */ //===============================================================
// Decrement the DBSession Count. GetSpecification is not
// possible anymore
//===============================================================
if( m_pCreator ){
//===========================================================
// Mark the session as not having an open rowset anymore
//===========================================================
m_pCreator->GetOuterUnknown()->Release(); }
SAFE_DELETE_ARRAY(m_strKey); SAFE_DELETE_ARRAY(m_strURL); //===============================================================
// 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.
//
// 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 CRow::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_IColumnsInfo) { *ppv = (LPVOID) m_pIColumnsInfo; } else if (riid == IID_IConvertType) { *ppv = (LPVOID) m_pIConvertType; } else if (riid == IID_IRow) { *ppv = (LPVOID) m_pIRow; } else if (riid == IID_IGetSession) { *ppv = (LPVOID) m_pIGetSession; } else if (riid == IID_IRowChange) { *ppv = (LPVOID) m_pIRowChange; } else if( riid == IID_ISupportErrorInfo) { *ppv = (LPVOID)m_pISupportErrorInfo; } else if(riid == IID_IScopedOperations || riid == IID_IBindResource) { *ppv = (LPVOID)m_pIScopedOperations; }
//======================================================
// 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
//
// Current reference count
//
/////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_( ULONG ) CRow::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 ) CRow::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; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// The first function called for the row for initialization of the class
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::InitRow(HROW hRow , CWbemClassWrapper *pInst , ROWCREATEBINDFLAG rowCreateFlag) { HRESULT hr = S_OK; DBCOLUMNINFO * pCol = NULL; CURLParser urlParser;
m_hRow = hRow; m_pInstance = (CWbemClassInstanceWrapper *)pInst;
//=================================================
// If the class is not created by the rowset then
//=================================================
if(m_pSourcesRowset == NULL) { BSTR strTemp; strTemp = Wmioledb_SysAllocString(m_strKey); urlParser.SetPath(strTemp); SysFreeString(strTemp); if(urlParser.GetURLType() == URL_EMBEDEDCLASS) {
GetEmbededInstancePtrAndSetMapClass(&urlParser); } else { VARIANT varDataSrc; VariantInit(&varDataSrc); m_pInstance = NULL; strTemp = Wmioledb_SysAllocString(m_strKey);
// If the object path is same as the data src then the object has
// to be obtained by just QI on the IWbemServicesEx pointer
if(SUCCEEDED(hr = m_pCreator->GetDataSrcProperty(DBPROP_INIT_DATASOURCE , varDataSrc)) && varDataSrc.vt == VT_BSTR && varDataSrc.bstrVal != NULL) { if(_wcsicmp(m_strKey,varDataSrc.bstrVal) == 0) { SAFE_FREE_SYSSTRING(strTemp); } } m_pInstance = (CWbemClassInstanceWrapper *)m_pMap->GetInstance(strTemp); SysFreeString(strTemp); } urlParser.GetURL(strTemp); m_strURL = new WCHAR[SysStringLen(strTemp) + 1]; // NTRaid:111801
// 06/07/00
if(m_strURL) { memset(m_strURL,0,(SysStringLen(strTemp) + 1) * sizeof(WCHAR)); memcpy(m_strURL,strTemp,SysStringLen(strTemp) * sizeof(WCHAR));
if( rowCreateFlag == ROWCREATE && m_pInstance != NULL) { hr = DB_E_RESOURCEEXISTS; } else { //=================================================
// If an existing instance is to be created
//=================================================
if( rowCreateFlag == ROWCREATE || rowCreateFlag == ROWOVERWRITE ) { //======================================================
// If instance already exists then delete the instance
//======================================================
if( m_pInstance != NULL) { m_pMap->DeleteInstance(m_pInstance); m_pInstance = NULL; } //===========================
// Create instance
//===========================
hr = CreateNewRow(&m_pInstance); } //=================================================================
// If instance is pointed by the path is not found return error
//=================================================================
if( m_pInstance == NULL) { hr = DB_E_NOTFOUND; } else {
/* //====================================================================
/// Get property and Set Serach Preferences
//====================================================================
hr = SetSearchPreferences();
//===================================================================================
// Get the column information
//===================================================================================
if(SUCCEEDED(hr = CBaseRowObj::GetColumnInfo())) { m_cTotalCols--; // Decrementing so as not to take into account the bookmark column
//===========================================================================
// Initialize the columns representing the qualifiers and embeded classes
//===========================================================================
if(m_cNestedCols > 0) for ( int iCol = 1 ; iCol < (int)m_Columns.GetTotalNumberOfColumns(); iCol++) { pCol = m_Columns.GetColInfo(iCol); if( pCol->wType == DBTYPE_HCHAPTER) { pCol->wType = DBTYPE_UI4; pCol->ulColumnSize = sizeof(ULONG); pCol->dwFlags = DBCOLUMNFLAGS_ISCOLLECTION; }
} } // Succeeded(GetCOlumnInfo())
*/ hr = S_OK; } // Else if instance pointed by path not found
} // else of if( rowCreateFlag == ROWCREATE && m_pInstance != NULL)
} // if(m_strUrl)
else { hr = E_OUTOFMEMORY; } } else { CBSTR strTemp; if(SUCCEEDED(hr = ((CWbemClassInstanceWrapper *)pInst)->GetKey(strTemp))) { m_strKey = new WCHAR [ SysStringLen(strTemp) + 1]; wcscpy(m_strKey,strTemp);
urlParser.SetPath(strTemp); strTemp.Clear(); strTemp.Unbind(); urlParser.GetURL((BSTR &)strTemp); m_strURL = new WCHAR[ SysStringLen(strTemp) + 1]; memset(m_strURL,0,(SysStringLen(strTemp) + 1) * sizeof(WCHAR)); memcpy(m_strURL,strTemp,SysStringLen(strTemp) * sizeof(WCHAR));
} }
if(SUCCEEDED(hr)) { //===========================================================================
// Call this function to allocate memory for all the contained interfaces
// and utility classes
//===========================================================================
if(SUCCEEDED(hr = AllocateInterfacePointers())) { if(m_pSourcesRowset != NULL) { m_cTotalCols = m_pSourcesRowset->m_Columns.GetTotalNumberOfColumns(); hr = GetRowColumnInfo(); } else { //====================================================================
/// Get property and Set Serach Preferences
//====================================================================
hr = SetSearchPreferences();
//===================================================================================
// Get the column information
//===================================================================================
if(SUCCEEDED(hr = CBaseRowObj::GetColumnInfo())) { m_cTotalCols--; // Decrementing so as not to take into account the bookmark column
//===========================================================================
// Initialize the columns representing the qualifiers and embeded classes
//===========================================================================
if(m_cNestedCols > 0) for ( int iCol = 1 ; iCol < (int)m_Columns.GetTotalNumberOfColumns(); iCol++) { pCol = m_Columns.GetColInfo(iCol); if( pCol->wType == DBTYPE_HCHAPTER) { pCol->wType = DBTYPE_UI4; pCol->ulColumnSize = sizeof(ULONG); pCol->dwFlags = DBCOLUMNFLAGS_ISCOLLECTION | DBCOLUMNFLAGS_ISCHAPTER; }
} } // Succeeded(GetCOlumnInfo())
m_pRowColumns = &m_Columns; } } // if Succeeded(hr)
} // If Succeeded(hr)
if(SUCCEEDED(hr)) { //==========================================================
// Call this function to initialize the ISupportErrorInfo;
//==========================================================
hr = AddInterfacesForISupportErrorInfo();
} return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// This first function called for the row for initialization of the class when a row is
// not created from rowset object
// An overloaded function
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::InitRow(LPWSTR strPath, LPWSTR strTableID , DWORD dwFlags, ROWCREATEBINDFLAG rowCreateFlag) {
HRESULT hr = S_OK; //=========================================================
// Call this function to Initialize and allocate WMIOledb
//=========================================================
hr = InitializeWmiOledbMap(strPath,strTableID,dwFlags);
if( SUCCEEDED(hr)) { hr = InitRow(0,0,rowCreateFlag); }
return hr; }
////////////////////////////////////////////////////////////////////////////////////////////
// Function to allocate contained interface pointers and also some utility classes
////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::AllocateInterfacePointers() { HRESULT hr = S_OK; if(m_pSourcesRowset == NULL) { m_pIConvertType = new CImpIConvertType(this); m_pUtilProp = new CUtilProp; // NTRaid: 136443
// 07/05/00
if(m_pUtilProp) { hr = m_pUtilProp->FInit(ROWSETPROP); } else { hr = E_OUTOFMEMORY; } } //=========================================================================
// if row is created from a rowset then create a columninfo manager
// instance , passing the source rowset as a parameter to constructor
//=========================================================================
else { m_pRowColumns = new cRowColumnInfoMemMgr(&m_pSourcesRowset->m_Columns); }
if(SUCCEEDED(hr)) { m_pIColumnsInfo = new CImpIColumnsInfo( this ); m_pIRow = new CImpIRow( this ); m_pIGetSession = new CImpIGetSession( this ); m_pIRowChange = new CImpIRowChange( this ); m_pISupportErrorInfo = new CImpISupportErrorInfo(this); m_pIScopedOperations = new CImpIScopedOperations(this);
if( ! (m_pIColumnsInfo && m_pUtilProp && m_pIRow && m_pIGetSession && m_pIRowChange && m_pIConvertType && m_pIScopedOperations)) { hr = E_OUTOFMEMORY; } }
return hr; }
////////////////////////////////////////////////////////////////////////////////////////////
// Function to allocate CWmiOledbMap class if row is not created from rowset
////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::InitializeWmiOledbMap(LPWSTR strPath, LPWSTR strTableID , DWORD dwFlags) { HRESULT hr = S_OK; assert(m_pSourcesRowset == NULL); CURLParser urlParser; CBSTR strTemp;
if(strPath == NULL ) { hr = E_INVALIDARG; } else { LONG lObjectType = -1; strTemp.SetStr(strPath); urlParser.SetPath(strTemp); lObjectType = urlParser.GetURLType(); if(lObjectType == URL_DATASOURCE && strTableID == NULL) { hr = E_INVALIDARG; } if(lObjectType == URL_DATASOURCE) // or scope
{ m_rowType = ROW_SCOPE; } }
if(SUCCEEDED(hr)) { dwFlags = dwFlags == -1 ? GetQualifierFlags(): dwFlags; if(m_rowType == ROW_SCOPE) // this happenes only the opened scope is a namespace
{ /*// m_pMap = new CWmiOleDBMap( strPath,
// m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon);
if(m_pMap) { // hr = m_pMap->FInit( strPath,m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon);
} else { hr = E_OUTOFMEMORY; } */ } else { m_pMap = new CWmiOleDBMap; if(m_pMap) { hr = m_pMap->FInit(dwFlags,strTableID,m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon); } else { hr = E_OUTOFMEMORY; } }
if(SUCCEEDED(hr)) { VARIANT varValue; VariantInit(&varValue); // Bug which not able to get system properties from Row object
// NTRaid: 145684
// 05/06/00
//===========================================================================================
// Get the DataSource property to check if system Properties is to be fetched?
//===========================================================================================
if(SUCCEEDED(hr = m_pCreator->GetDataSrcProperty(DBPROP_WMIOLEDB_SYSTEMPROPERTIES,varValue))) { if( varValue.boolVal == VARIANT_TRUE) { m_pMap->SetSytemPropertiesFlag(TRUE); }
m_strKey = new WCHAR [wcslen(strPath) + 1]; if(m_strKey == NULL) { hr = E_OUTOFMEMORY; } else { wcscpy(m_strKey,strPath); m_pMap->AddRef(); } } VariantClear(&varValue); } }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to add interfaces to ISupportErrorInfo interface
/////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::AddInterfacesForISupportErrorInfo() { HRESULT hr = S_OK;
if( SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IColumnsInfo)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IConvertType)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IGetSession)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRowChange)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IScopedOperations)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IBindResource))) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IRow); }
return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////
// Function to the get the value of the columns requested
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetColumns(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[ ]) { HRESULT hr = E_FAIL;
for( ULONG_PTR lIndex = 0 ; lIndex < cColumns ; lIndex++) { //=============================================
// Initialize the output memeber variables
//=============================================
rgColumns[lIndex].cbDataLen = 0; rgColumns[lIndex].dwStatus = DBSTATUS_S_OK; }
//======================================================
// if the row object is created by the rowset then
// get the data maintained by the rowset object
//======================================================
if(m_pSourcesRowset != NULL) { hr = GetColumnsFromRowset(cColumns,rgColumns); } else { /// Get data for the requested columns
hr = GetRowData(cColumns,rgColumns); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to the get the value of the columns when row object is created from rowset
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetColumnsFromRowset(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[]) { DBORDINAL icol; ROWBUFF *pRowBuff; COLUMNDATA *pColumnData; DBCOUNTITEM ulErrorCount = 0; DBTYPE dwSrcType; DBTYPE dwDstType; void *pSrc; void *pDst; DBLENGTH ulSrcLength; DBLENGTH *pulDstLength; DBLENGTH ulDstMaxLength; DBSTATUS dwSrcStatus; DBSTATUS *pdwDstStatus; HRESULT hr = S_OK; DBSTATUS dwStatus = DBSTATUS_S_OK; CDataMap dataMap; BOOL bUseDataConvert = TRUE; VARIANT varValue;
VariantInit(&varValue);
//=========================================================
// Check if the row is already deleted
//=========================================================
dwStatus = m_pSourcesRowset->GetRowStatus(m_hRow); if( dwStatus != DBROWSTATUS_S_OK) { if(dwStatus == DBROWSTATUS_E_DELETED) { hr = DB_E_DELETEDROW; } else { hr = E_FAIL; } }
if( SUCCEEDED(hr)) { //=========================================================
// if data is not yet received then fetch the data
//=========================================================
if(S_OK != m_pSourcesRowset->IsSlotSet(m_hRow)) { hr = m_pSourcesRowset->GetData(m_hRow); } if(SUCCEEDED(hr)) { if( (m_pSourcesRowset->m_ulProps & OTHERUPDATEDELETE) &&(m_pSourcesRowset->m_ulLastFetchedRow != m_hRow)) { if(SUCCEEDED(hr = m_pSourcesRowset->GetDataToLocalBuffer(m_hRow))) { m_pSourcesRowset->m_ulLastFetchedRow = m_hRow; } }
if(SUCCEEDED(hr)) { //=========================================================
// Get the pointer to the rowbuffer
//=========================================================
pRowBuff = m_pSourcesRowset->GetRowBuff(m_hRow , TRUE);
assert(pRowBuff != NULL);
// Navigate for each requested column
for( ULONG lIndex = 0 ; lIndex < cColumns ; lIndex++) { bUseDataConvert = TRUE; // if the column is a bookmark then continue without doing anything
if(rgColumns[lIndex].columnid.eKind == DBKIND_GUID_PROPID && rgColumns[lIndex].columnid.uGuid.guid == DBCOL_SPECIALCOL && rgColumns[lIndex].columnid.uName.ulPropid >= 2) { if(m_pSourcesRowset->m_ulProps & BOOKMARKPROP) { dwSrcType = DBTYPE_I4; pSrc = &pRowBuff->dwBmk; ulSrcLength = pRowBuff->cbBmk; dwSrcStatus = DBSTATUS_S_OK; icol = 0; } else { continue; } } else { //=================================================================
// If the columnID is not of type name then set the status
// to unavialable as only this is supported
//=================================================================
if(rgColumns[lIndex].columnid.eKind != DBKIND_NAME) { rgColumns[lIndex].dwStatus = DBSTATUS_E_UNAVAILABLE; continue; }
icol = m_pSourcesRowset->GetOrdinalFromColName(rgColumns[lIndex].columnid.uName.pwszName);
//=========================================================================================
// The column unavailable for the row as the class qualifier belongs to a parent rowset
//=========================================================================================
if(S_OK == (hr =m_pCreator->GetDataSrcProperty(DBPROP_WMIOLEDB_QUALIFIERS,varValue))) if( (varValue.lVal & CLASS_QUALIFIERS) && m_bClassChanged && icol == 1 && m_pRowColumns->ColumnType(icol) == DBTYPE_HCHAPTER) { rgColumns[lIndex].dwStatus = DBSTATUS_E_UNAVAILABLE; continue; } //=================================================================
// If the requested column is not part of the source rowset
// get it directly from the instance
//=================================================================
if((DB_LORDINAL) icol == -1) { hr = GetColumnData(rgColumns[lIndex]); if ( hr != S_OK ) { ulErrorCount++; } continue; } pColumnData = (COLUMNDATA *) ((BYTE *) pRowBuff + m_pSourcesRowset->m_Columns.GetDataOffset(icol));
dwSrcType = (SHORT)pColumnData->dwType;
if( dwSrcType == DBTYPE_BSTR) { pSrc = &(pColumnData->pbData); } else { pSrc = (pColumnData->pbData); }
ulSrcLength = pColumnData->dwLength; dwSrcStatus = pColumnData->dwStatus; } ulDstMaxLength = rgColumns[lIndex].cbMaxLen; dwDstType = rgColumns[lIndex].wType;
pDst = rgColumns[lIndex].pData; pulDstLength = &rgColumns[lIndex].cbDataLen; pdwDstStatus = &rgColumns[lIndex].dwStatus;
//==========================================================
// if the column is of type chapter then consider that
// as a of type long as HCHAPTER is a ULONG value
//==========================================================
if(dwSrcType == DBTYPE_HCHAPTER) { dwSrcType = DBTYPE_UI4; }
if(dwDstType == DBTYPE_HCHAPTER) { dwDstType = DBTYPE_UI4; }
//=================================================================
// if both the source and destination type is array then don't
// use IDataConvert::DataConvert for conversion
//=================================================================
if( (dwSrcType & DBTYPE_ARRAY) && (dwDstType & DBTYPE_ARRAY) ) { bUseDataConvert = FALSE; }
if( dwSrcType != VT_NULL && dwSrcType != VT_EMPTY && bUseDataConvert == TRUE && pSrc != NULL) { // NTRaid:138957
// since for DBTYPE_UI4 the data returned from WMI
// is of type DBTYPE_I4 changing the source type does not
// have any effect except that the VARIANT type of the
// output will be VT_I4 instead of VT_UI4
DBTYPE dbSrcType = dwSrcType; if(dwDstType == DBTYPE_VARIANT) { dbSrcType = GetVBCompatibleAutomationType(dwSrcType); } hr = g_pIDataConvert->DataConvert( dbSrcType, dwDstType, ulSrcLength, pulDstLength, pSrc, pDst, ulDstMaxLength, dwSrcStatus, pdwDstStatus, rgColumns[lIndex].bPrecision, // bPrecision for conversion to DBNUMERIC
rgColumns[lIndex].bScale, // bScale for conversion to DBNUMERIC
DBDATACONVERT_DEFAULT);
if(hr == DB_E_UNSUPPORTEDCONVERSION && pdwDstStatus != NULL) { *pdwDstStatus = DBSTATUS_E_CANTCONVERTVALUE; } } else if(bUseDataConvert == FALSE && pSrc != NULL) { //=================================================================
// Call this function to get the array in the destination address
//=================================================================
hr = dataMap.ConvertAndCopyArray((SAFEARRAY *)pSrc,(SAFEARRAY **)pDst, dwSrcType,dwDstType,pdwDstStatus); if( *pdwDstStatus == DBSTATUS_E_CANTCONVERTVALUE) { *pulDstLength = 0; }
} else { *pulDstLength = 0; *pdwDstStatus = DBSTATUS_S_ISNULL; }
//===================================================================
// Ignoring the array for the time being
// to be removed later
//===================================================================
if(dwSrcType & VT_ARRAY) { hr = S_OK; }
if (hr != S_OK ) { ulErrorCount++; // can't coerce
hr = S_OK; } } // for loop
} // if succeeded(hr) after getting local buffer address
} // if Succeeded(hr) after getting the slot number
} // if Succeeded(hr) after initial checking
//===================================================================
// We report any lossy conversions with a special status.
// Note that DB_S_ERRORSOCCURED is a success, rather than failure.
//===================================================================
if ( SUCCEEDED(hr) ) { hr = ( ulErrorCount ? DB_S_ERRORSOCCURRED : S_OK ); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to update a row
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::UpdateRow(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[ ]) { VARIANT varProp; HRESULT hr = E_FAIL;
VariantInit(&varProp);
if(m_pSourcesRowset != NULL) { //===================================================================
// Check if updatibility is supported by the parent rowset
//===================================================================
if(SUCCEEDED(hr = m_pSourcesRowset->GetRowsetProperty(DBPROP_UPDATABILITY , varProp))) { //=========================================================
// If the rowset is not updatable then return failure
//=========================================================
if(!( varProp.lVal & DBPROPVAL_UP_CHANGE)) { hr = E_FAIL; } else { hr = UpdateColumnsFromRowset(cColumns,rgColumns); } }
} else { hr = SetRowData(cColumns,rgColumns); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////
// Function to update a row when it is created by a rowset
/////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::UpdateColumnsFromRowset(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[ ]) { DBORDINAL icol; ROWBUFF *pRowBuff; COLUMNDATA *pColumnData; DBCOUNTITEM ulErrorCount = 0; DBTYPE dwSrcType; DBTYPE dwDstType; void *pSrc; void *pDst; void *pTemp; DBLENGTH ulSrcLength; DBLENGTH ulDstLength; DBLENGTH ulDstMaxLength; DBSTATUS dwSrcStatus; DBSTATUS dwDstStatus; HRESULT hr = S_OK; DBSTATUS dwStatus = DBSTATUS_S_OK; CVARIANT cvarData; VARIANT *pvarData = &cvarData; CDataMap map; ULONG lFlags = 0; BOOL bUseDataConvert = TRUE; DWORD dwCIMType = 0;
dwStatus = m_pSourcesRowset->GetRowStatus(m_hRow); if( dwStatus != DBROWSTATUS_S_OK) { if(dwStatus == DBROWSTATUS_E_DELETED) { hr = DB_E_DELETEDROW; } else { hr = E_FAIL; } } else { //========================================================
// if data is not yet received then fetch the data
//========================================================
if(S_OK != m_pSourcesRowset->IsSlotSet(m_hRow)) { hr = m_pSourcesRowset->GetData(m_hRow); } if(SUCCEEDED(hr)) { //========================================
// Get the pointer to the rowbuffer
//========================================
pRowBuff = m_pSourcesRowset->GetRowBuff(m_hRow , TRUE);
assert(pRowBuff != NULL);
for( ULONG lIndex = 0 ; lIndex < cColumns ; lIndex++) { bUseDataConvert = TRUE; if(rgColumns[lIndex].columnid.eKind != DBKIND_NAME) { rgColumns[lIndex].dwStatus = DBSTATUS_E_UNAVAILABLE; continue; }
icol = m_pSourcesRowset->GetOrdinalFromColName(rgColumns[lIndex].columnid.uName.pwszName);
//===================================================================================
// If the requested column is not part of the source rowset
// call SetColumnData function to set it directly from the instance
//===================================================================================
if((DB_LORDINAL)icol < 0) { hr = SetColumnData(rgColumns[lIndex]); if ( hr != S_OK ) { ulErrorCount++; } continue; }
pColumnData = (COLUMNDATA *) ((BYTE *) pRowBuff + m_pSourcesRowset->m_Columns.GetDataOffset(icol));
//==================================================
// check if the column is readonly or not
//==================================================
lFlags = m_pSourcesRowset->m_Columns.ColumnFlags(icol); if((m_pSourcesRowset->m_Columns.ColumnFlags(icol) & DBCOLUMNFLAGS_WRITE) == 0) { pColumnData->dwStatus = DBSTATUS_E_READONLY; ulErrorCount++; continue; }
dwSrcType = rgColumns[lIndex].wType; ulSrcLength = rgColumns[lIndex].cbDataLen; dwSrcStatus = rgColumns[lIndex].dwStatus; pSrc = rgColumns[lIndex].pData; ulDstMaxLength = -1; dwDstType = (SHORT)pColumnData->dwType; // pDst = &varData;
//==========================================================
// if the column is of type chapter then consider that
// as a of type long as HCHAPTER is a ULONG value
//==========================================================
if(dwSrcType == DBTYPE_HCHAPTER) { dwSrcType = DBTYPE_UI4; }
if(dwDstType == DBTYPE_HCHAPTER) { dwDstType = DBTYPE_UI4; }
hr = g_pIDataConvert->GetConversionSize(dwSrcType, dwDstType, &ulSrcLength, &ulDstLength, pSrc); try { pDst = new BYTE[ulDstLength]; } catch(...) { SAFE_DELETE_ARRAY(pDst); throw; }
//===================================================================================
// if both the source and destination type is array then don't
// use IDataConvert::DataConvert for conversion
//===================================================================================
if( (dwSrcType & DBTYPE_ARRAY) && (dwDstType & DBTYPE_ARRAY) ) { bUseDataConvert = FALSE; }
// this function is called to check for some non automation types
dwSrcType = GetVBCompatibleAutomationType(dwSrcType); //===================================================================================
// If the source type is not array or empty or null the use the conversion library
// for converting the data
//===================================================================================
if( dwSrcType != VT_NULL && dwSrcType != VT_EMPTY && bUseDataConvert == TRUE && pSrc != NULL) { hr = g_pIDataConvert->DataConvert( dwSrcType, dwDstType, ulSrcLength, &ulDstLength, pSrc, pDst, ulDstMaxLength, dwSrcStatus, &dwDstStatus, 0, // bPrecision for conversion to DBNUMERIC
0, // bScale for conversion to DBNUMERIC
DBDATACONVERT_DEFAULT);
if(hr == DB_E_UNSUPPORTEDCONVERSION ) { dwDstStatus = DBSTATUS_E_CANTCONVERTVALUE; } } else if(bUseDataConvert == FALSE && pSrc != NULL) { //==================================================================
// Call this function to get the array in the destination address
//==================================================================
hr = map.ConvertAndCopyArray((SAFEARRAY *)pSrc,(SAFEARRAY **)pDst, dwSrcType,dwDstType, &dwDstStatus); if(dwDstStatus == DBSTATUS_E_CANTCONVERTVALUE) { ulDstLength = 0; ulErrorCount++; } } else { pDst = NULL; ulDstLength = 0; dwDstStatus = DBSTATUS_S_ISNULL; }
if( hr == S_OK) { 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(pDst != NULL && pColumnData->dwType == VT_BSTR) { pTemp = *(BSTR **)pDst; } else { pTemp = pDst; } //====================================
// If data is is modified then
//====================================
if((map.CompareData(dwDstType,pColumnData->pbData,pTemp) == FALSE) && !( pColumnData->pbData == NULL && ulDstLength == 0)) { //===============================
// Release the Old data
//===============================
pColumnData->ReleaseColumnData(); if(ulDstLength > 0) { //=====================================================================
// Convert the new data to Variant. This function return the status
// if not able to conver the data
//=====================================================================
hr = map.MapAndConvertOLEDBTypeToCIMType((USHORT)pColumnData->dwType,pTemp,ulDstLength,*pvarData,dwCIMType); } if( hr == S_OK) { hr = pColumnData->SetData(cvarData,dwDstType);
//==============================
// Set the data to modified
//==============================
pColumnData->dwStatus |= COLUMNSTAT_MODIFIED; cvarData.Clear(); } else { //==============================
// Set the data to modified
//==============================
pColumnData->dwStatus |= hr; ulErrorCount++;
} } } else { ulErrorCount++; rgColumns[lIndex].dwStatus = dwDstStatus; }
SAFE_DELETE_ARRAY(pDst); } // for loop
//===============================================================
// if the error count is less than the number of columns
// then there is atleast one column to be updated
//===============================================================
if( ulErrorCount < cColumns) { //====================================================================
// Update the the row
//====================================================================
hr = m_pSourcesRowset->UpdateRowData(m_hRow,cColumns,rgColumns); }
//===================================================================
// We report any lossy conversions with a special status.
// Note that DB_S_ERRORSOCCURED is a success, rather than failure.
//===================================================================
if ( SUCCEEDED(hr) ) { hr = ( ulErrorCount ? DB_S_ERRORSOCCURRED : S_OK ); } } } // else of check if deleted
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Virtual overridden function which is called from IColumnInfo to get the column information
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetColumnInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo,WCHAR** ppStringsBuffer) { DBORDINAL icol = 0; DBCOLUMNINFO* rgdbcolinfo = NULL; WCHAR* pstrBuffer = NULL; WCHAR* pstrBufferForColInfo = NULL; HRESULT hr = S_OK; ptrdiff_t dp; DBCOUNTITEM cSourcesCol = 0;
if(SUCCEEDED(hr = m_pRowColumns->CopyColumnInfoList(rgdbcolinfo,(m_pSourcesRowset != NULL)))) { //=========================================================================
// Copy the heap for column names.
//=========================================================================
if (m_pSourcesRowset != NULL && m_pRowColumns->ColumnNameListStartingPointOfSrcRs() != NULL){
hr = m_pRowColumns->CopyColumnNamesList(pstrBuffer); if( hr != S_OK || pstrBuffer == NULL) { hr = E_OUTOFMEMORY; } else { //==================================================================================
// This will give the starting pointer difference to the columns names of the
// source rowset
//==================================================================================
dp = (LONG_PTR) pstrBuffer - (LONG_PTR) (m_pRowColumns->ColumnNameListStartingPointOfSrcRs()); dp >>= 1;
//=========================================================================
// Loop through columns and adjust pointers
// to column names.
//=========================================================================
cSourcesCol = m_pRowColumns->GetNumberOfColumnsInSourceRowset(); for ( icol =0; icol < cSourcesCol; icol++ ) { if ( rgdbcolinfo[icol].pwszName ) { rgdbcolinfo[icol].pwszName += dp; } if(rgdbcolinfo[icol].wType == DBTYPE_HCHAPTER) { rgdbcolinfo[icol].dwFlags = DBCOLUMNFLAGS_ISCOLLECTION | DBCOLUMNFLAGS_ISCHAPTER ; } }
//==================================================================================================================
// This will give the starting pointer difference to the columns names of the columns which is not present in the
// sources rowset
// Here the number of bytes copied for source rowset column names has to be taken care of
//==================================================================================================================
dp = (LONG_PTR) pstrBuffer + m_pRowColumns->GetCountOfBytesCopiedForSrcRs() - (LONG_PTR) (m_pRowColumns->ColumnNameListStartingPoint()); dp >>= 1; }
} else { if( SUCCEEDED(hr = m_pRowColumns->CopyColumnNamesList(pstrBuffer))) { //================================================================================
// This will give the starting pointer difference to the columns names of the
// source rowset
//================================================================================
dp = (LONG_PTR) pstrBuffer - (LONG_PTR) (m_pRowColumns->ColumnNameListStartingPoint()); dp >>= 1; icol = 0; } }
if(SUCCEEDED(hr)) { //===========================================
// Loop through columns and adjust pointers
// to column names.
//===========================================
for ( ; icol < m_cTotalCols ; icol++ ) { if ( rgdbcolinfo[icol].pwszName ) { rgdbcolinfo[icol].pwszName += dp; }
}
//=======================================================
// If the row's column is of type HCHAPTER change it
// to empty and the flag to DBCOLUMNFLAGS_ISCOLLECTION
//=======================================================
if(m_cNestedCols > 0) for(icol = 0; icol < m_cTotalCols ; icol++) { if(rgdbcolinfo[icol].wType == DBTYPE_HCHAPTER) { rgdbcolinfo[icol].wType = DBTYPE_HCHAPTER; rgdbcolinfo[icol].dwFlags = DBCOLUMNFLAGS_ISCHAPTER | DBCOLUMNFLAGS_ISCOLLECTION; rgdbcolinfo[icol].ulColumnSize = sizeof(DBLENGTH); } }
//===================================================================================================
// Setting the output parameters
//===================================================================================================
*prgInfo = &rgdbcolinfo[0]; *ppStringsBuffer = pstrBuffer; *pcColumns = m_cTotalCols; } // if succeeded(hr)
} // if succeeded(CopyColumnInfoList())
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to get the column information of the row. THis function check if the class name of the
// rowset which created the row belongs to the same class as that of the instance pointing the current row
// If these two are different , this ffunction get the col info for this row
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetRowColumnInfo() { WCHAR *pstrRsClassName = NULL, *pstrRowClassName = NULL; HRESULT hr = S_OK;
//====================================================
// Get the class name to which the instance belongs
//====================================================
pstrRowClassName = m_pInstance->GetClassName(); if( pstrRowClassName != NULL) { //================================================
// Get the class name of the source rowset
//================================================
pstrRsClassName = m_pSourcesRowset->m_pMap->GetClassName(); } //============================================================
// Set the bClassChanged flag to true if instance points to
// different class than that of the source rowset
//============================================================
if( pstrRsClassName == NULL && pstrRowClassName == NULL) { m_bClassChanged = FALSE; } else if( pstrRsClassName == NULL || pstrRowClassName == NULL) { m_bClassChanged = TRUE; } else if(_wcsicmp(pstrRsClassName,pstrRowClassName) != 0) { m_bClassChanged = TRUE; } //=====================================================================
// If the source rowset and the row points to different classes ,
// then the columnd info of the remaining columns has to be obtained
//=====================================================================
if(m_bClassChanged == TRUE) { //===========================================
// Get the flags of the source rowset
//===========================================
DWORD dwFlags = m_pInstance->GetFlags(); SAFE_RELEASE_PTR(m_pMap); //===================================
// Create a new map class
//===================================
m_pMap = new CWmiOleDBMap; if(m_pMap == NULL) { hr = E_OUTOFMEMORY; } else { if(SUCCEEDED(hr = m_pMap->FInit(dwFlags,pstrRowClassName, m_pCon == NULL ?m_pCreator->m_pCDataSource->m_pWbemWrap: m_pCon))) { m_pMap->AddRef();
//============================
// Get the column info
//============================
hr = GetColumnInfo(); } } }
SAFE_DELETE_ARRAY(pstrRowClassName);
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the number of columns in the row and allocate memory
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetColumnInfo() { HRESULT hr = S_OK; VARIANT varValue;
VariantInit(&varValue);
// Bug which not able to get system properties from Row object
// NTRaid: 140657
// 05/06/00
//===========================================================================================
// Get the DataSource property to check if system Properties is to be fetched?
//===========================================================================================
if(SUCCEEDED(hr = m_pCreator->GetDataSrcProperty(DBPROP_WMIOLEDB_SYSTEMPROPERTIES,varValue))) { if( varValue.boolVal == VARIANT_TRUE) { m_pMap->SetSytemPropertiesFlag(TRUE); }
//==================================================================================
// switch on type of the qualifier. If it is 0 then the recordset is
// representing the instances of the class
//==================================================================================
switch( m_uRsType) { case 0 :
//==================================================================================
// Get the count of columns in the table
//==================================================================================
hr = m_pMap->GetColumnCount(m_cTotalCols,m_cCols,m_cNestedCols);
// If source rowset is present and
// If the property for showing system property is false and
// if the source rowset is created by a query of mixed type
// ( meaning rowset created executing a query, which results
// in heterogenous objects ) then add another column to the row
// which is part of the source rowset to show __PATH
// NTRaid : 142133 & 141923
// 07/12/00
if(m_pSourcesRowset != NULL && m_cTotalCols) { if( varValue.boolVal == FALSE) { // all types of rowset has to have an extr column as __PATH property
// which is a system property is shown in the row even if the
// DBPROP_WMIOLEDB_SYSTEMPROPERTIES is set to FALSE
if(NORMAL != m_pSourcesRowset->GetObjListType()) { m_cTotalCols++; m_cCols++; } } VariantClear(&varValue); }
break;
case PROPERTYQUALIFIER : case CLASSQUALIFIER:
//==================================================================================
// Get the number of columns for the property qualifier
//==================================================================================
m_cCols = NUMBER_OF_COLUMNS_IN_QUALIFERROWSET + 1; // for bookmarkcolumn
m_cTotalCols = m_cCols; break;
}; }
if( SUCCEEDED(hr)) { // The column unavailable for the row as the class qualifier belongs to a parent rowset
if(m_pSourcesRowset != NULL && S_OK == (hr =m_pCreator->GetDataSrcProperty(DBPROP_WMIOLEDB_QUALIFIERS,varValue))) if( (varValue.lVal & CLASS_QUALIFIERS) && m_bClassChanged) { m_cTotalCols++; // This is to accomodate another column which actually
// holds the class/instance qualifiers
}
if( S_OK == (hr = m_pRowColumns->AllocColumnNameList(m_cTotalCols))){
//===============================================================================
// Allocate the DBCOLUMNINFO structs to match the number of columns
//===============================================================================
if( S_OK == (hr = m_pRowColumns->AllocColumnInfoList(m_cTotalCols))){ hr = GatherColumnInfo(); } } }
//==================================================================================
// Free the columnlist if more is allocated
//==================================================================================
if( hr != S_OK ){ m_pRowColumns->FreeColumnNameList(); m_pRowColumns->FreeColumnInfoList(); }
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the col info for row
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GatherColumnInfo() { HRESULT hr = S_OK;
switch( m_uRsType) { case 0 :
//=============================================================
// Get Column Names and Lengths
//=============================================================
hr = m_pMap->GetColumnInfoForParentColumns(m_pRowColumns); break;
case PROPERTYQUALIFIER:
//==================================================================================
// Get the number of columns for the property qualifier
//==================================================================================
hr = CBaseRowObj::GatherColumnInfoForQualifierRowset(); break;
case CLASSQUALIFIER: break;
};
if(SUCCEEDED(hr)) { m_cbRowSize = m_pRowColumns->SetRowSize(); hr = m_pRowColumns->FreeUnusedMemory(); }
return hr; }
//////////////////////////////////////////////////////////////////////////////////////
// Get data for a particular column
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetColumnData(DBCOLUMNACCESS &col) { DBORDINAL icol = 0; DBCOUNTITEM ulErrorCount = 0; CIMTYPE cimType = 0; DBTYPE dwSrcType; DBTYPE dwDstType; void *pSrc = NULL; void *pDst = NULL; BYTE *pTemp = NULL; DBLENGTH ulSrcLength; DBLENGTH *pulDstLength = NULL; DBLENGTH ulDstMaxLength = NULL; DBSTATUS dwSrcStatus = 0; DBSTATUS *pdwDstStatus = NULL; HRESULT hr = S_OK; DBSTATUS dwStatus = DBSTATUS_S_OK; BSTR strProp = NULL; DWORD dwFlags = 0; CDataMap map; BOOL bUseDataConvert = TRUE; DBORDINAL lCollectionColData = 0;
icol = m_pRowColumns->GetColOrdinal(col.columnid.uName.pwszName);
if( icol > 0) { // If the column is of type HCHAPTER or if it is a collection ( meaning
// if the column represents any of the child rowsets) then set the
// column to ordinal of the column
if(m_pRowColumns->ColumnType(icol) == DBTYPE_HCHAPTER || m_pRowColumns->ColumnFlags(icol) & DBCOLUMNFLAGS_ISCOLLECTION || m_pRowColumns->ColumnFlags(icol) & DBCOLUMNFLAGS_ISCHAPTER) { col.bPrecision = 0; col.bScale = 0; lCollectionColData = icol;
dwSrcType = DBTYPE_UI4; ulDstMaxLength = col.cbMaxLen; dwDstType = (DBTYPE)col.wType; pulDstLength = &col.cbDataLen; pdwDstStatus = &col.dwStatus; ulSrcLength = sizeof(lCollectionColData); dwSrcStatus = DBSTATUS_S_OK; pSrc = &lCollectionColData;
hr = S_OK; } else { strProp = Wmioledb_SysAllocString(col.columnid.uName.pwszName); hr = m_pMap->GetProperty(m_pInstance,strProp, pTemp,dwSrcType ,ulSrcLength, dwFlags ); if(SUCCEEDED(hr)) { // dwSrcType = (DBTYPE)cimType;
//==========================================
// check if the column is readonly or not
//==========================================
if((dwFlags & DBCOLUMNFLAGS_WRITE) == 0) { col.dwStatus = DBSTATUS_E_READONLY; } //=========================================================
// if the data is null set the status to null and return
//=========================================================
if(pTemp == NULL) { col.dwStatus = DBSTATUS_S_ISNULL; hr = S_OK; } else { if( dwSrcType == DBTYPE_BSTR) { pSrc = &pTemp; } else { pSrc = pTemp; } ulDstMaxLength = col.cbMaxLen; dwDstType = (DBTYPE)col.wType; pulDstLength = &col.cbDataLen; pdwDstStatus = &col.dwStatus;
} } SAFE_FREE_SYSSTRING(strProp); }
if(SUCCEEDED(hr)) { //==========================================================
// if the column is of type chapter then consider that
// as a of type long as HCHAPTER is a ULONG value
//==========================================================
if(dwSrcType == DBTYPE_HCHAPTER) { dwSrcType = DBTYPE_UI4; } if(dwDstType == DBTYPE_HCHAPTER) { dwDstType = DBTYPE_UI4; } pDst = (BYTE *)col.pData;
// if both the source and destination type is array then don't
// use IDataConvert::DataConvert for conversion
// Arrays are requested as VARIANTS then also do conversion using our conversion routine
// and fill the variant
if( (dwSrcType & DBTYPE_ARRAY) && ( (dwDstType & DBTYPE_ARRAY) || dwDstType == VT_VARIANT) ) { bUseDataConvert = FALSE; }
// this function is called to check for some non automation types
dwSrcType = GetVBCompatibleAutomationType(dwSrcType); // this function is called to check for some non automation types
dwDstType = GetVBCompatibleAutomationType(dwDstType); // If the source type is not array or empty or null the use the conversion library
// for converting the data
if( dwSrcType != VT_NULL && dwSrcType != VT_EMPTY && bUseDataConvert == TRUE && pSrc != NULL) { hr = g_pIDataConvert->DataConvert( (USHORT)dwSrcType, dwDstType, ulSrcLength, pulDstLength, pSrc, pDst, ulDstMaxLength, dwSrcStatus, pdwDstStatus, 0, // bPrecision for conversion to DBNUMERIC
0, // bScale for conversion to DBNUMERIC
DBDATACONVERT_DEFAULT);
if(hr == DB_E_UNSUPPORTEDCONVERSION && pdwDstStatus != NULL) { *pdwDstStatus = DBSTATUS_E_CANTCONVERTVALUE; }
if ( hr != S_OK) { ulErrorCount++; } } else if(bUseDataConvert == FALSE && pSrc != NULL) { SAFEARRAY *pArray = NULL; SAFEARRAY **pTemp = NULL; if(pDst != NULL) { pTemp = (SAFEARRAY **)pDst; if(dwDstType == VT_VARIANT) { pTemp = &pArray; } }
// Call this function to get the array in the destination address
hr = map.ConvertAndCopyArray((SAFEARRAY *)pSrc,pTemp, dwSrcType,dwDstType,pdwDstStatus); if( *pdwDstStatus == DBSTATUS_E_CANTCONVERTVALUE) { pulDstLength = 0; } if(SUCCEEDED(hr) && dwDstType == VT_VARIANT) { VariantInit((VARIANT *)pDst); if(pArray && pDst != NULL) { ((VARIANT *)pDst)->vt = VT_ARRAY | VT_VARIANT; ((VARIANT *)pDst)->parray = pArray; } } } else { if(pulDstLength) { *pulDstLength = 0; } if(pdwDstStatus) { *pdwDstStatus = DBSTATUS_S_ISNULL; } } //===============================
// Free the data allocated
//===============================
map.FreeData(dwSrcType , pTemp); } } else { col.dwStatus = DBSTATUS_E_UNAVAILABLE; hr = E_FAIL; }
return hr; }
//////////////////////////////////////////////////////////////////////////////////////
// Set a value of a particular column
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::SetColumnData(DBCOLUMNACCESS &col,BOOL bNewRow) { DBORDINAL icol; DBCOUNTITEM ulErrorCount = 0; DBTYPE dwSrcType; DBTYPE dwDstType; void *pSrc = NULL; void *pDst = NULL; void *pTemp = NULL; DBLENGTH lSrcLength; DBLENGTH lDstLength; DBLENGTH lDstMaxLength; DBSTATUS dwSrcStatus; DBSTATUS dwDstStatus; HRESULT hr = S_OK; CVARIANT cvarData; VARIANT *pvarData = &cvarData; CDataMap map; ULONG lFlags = 0; BSTR strProp; BOOL bUseDataConvert = TRUE; DWORD dwCIMType = 0;
//===============================================================
// Get the ordinal of the column from the column information
//===============================================================
icol = m_pRowColumns->GetColOrdinal(col.columnid.uName.pwszName);
if( ((LONG)icol) >= 0) {
strProp = Wmioledb_SysAllocString(col.columnid.uName.pwszName); //================================================
// check if the column is readonly or not
// If it is a new row continue updating
//================================================
lFlags = m_pRowColumns->ColumnFlags(icol); if(((bNewRow == FALSE) && ((m_pRowColumns->ColumnFlags(icol) & DBCOLUMNFLAGS_WRITE) == 0)) || ((bNewRow == TRUE) && m_pMap->IsSystemProperty(strProp))) { col.dwStatus = DBSTATUS_E_READONLY; ulErrorCount++; hr = DB_S_ERRORSOCCURRED; } else {
dwSrcType = col.wType; lSrcLength = col.cbDataLen; dwSrcStatus = col.dwStatus;
if(dwSrcType == DBTYPE_BSTR) { pSrc = &col.pData; } else { pSrc = col.pData; } lDstMaxLength = -1; dwDstType = (SHORT)m_pRowColumns->ColumnType(icol);
//==========================================================
// if the column is of type chapter then consider that
// as a of type long as HCHAPTER is a ULONG value
//==========================================================
if(dwSrcType == DBTYPE_HCHAPTER) { dwSrcType = DBTYPE_UI4; } if(dwDstType == DBTYPE_HCHAPTER) { dwDstType = DBTYPE_UI4; }
hr = g_pIDataConvert->GetConversionSize(dwSrcType, dwDstType, &lSrcLength, &lDstLength, pSrc);
try { pDst = new BYTE[lDstLength]; } catch(...) { SAFE_DELETE_ARRAY(pDst); throw; }
// if both the source and destination type is array then don't
// use IDataConvert::DataConvert for conversion
if((dwSrcType & DBTYPE_ARRAY) && (dwDstType & DBTYPE_ARRAY)) { bUseDataConvert = FALSE; } // this function is called to check for some non automation types
dwSrcType = GetVBCompatibleAutomationType(dwSrcType); // If the source type is not array or empty or null the use the conversion library
// for converting the data
if( dwSrcType != VT_NULL && dwSrcType != VT_EMPTY && bUseDataConvert == TRUE && pSrc != NULL) { hr = g_pIDataConvert->DataConvert( dwSrcType, dwDstType, lSrcLength, &lDstLength, pSrc, pDst, lDstMaxLength, dwSrcStatus, &dwDstStatus, 0, // bPrecision for conversion to DBNUMERIC
0, // bScale for conversion to DBNUMERIC
DBDATACONVERT_DEFAULT);
if(hr == DB_E_UNSUPPORTEDCONVERSION ) { dwDstStatus = DBSTATUS_E_CANTCONVERTVALUE; } } else if(bUseDataConvert == FALSE && pSrc != NULL) { // Call this function to get the array in the destination address
hr = map.ConvertAndCopyArray((SAFEARRAY *)pSrc,(SAFEARRAY **)pDst, dwSrcType,dwDstType,&dwDstStatus); if( dwDstStatus == DBSTATUS_E_CANTCONVERTVALUE) { lDstLength = 0; } } else { lDstLength = 0; dwDstStatus = DBSTATUS_S_ISNULL; }
if(SUCCEEDED(hr)) { 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(dwDstType & DBTYPE_ARRAY) { dwCIMType = m_Columns.GetCIMType(icol); }
if(pDst != NULL && dwDstType == VT_BSTR) { pTemp = *(BSTR **)pDst; } else { pTemp = pDst; }
//=========================================
// If data is is modified then
//=========================================
if( pTemp != NULL && lDstLength != 0) { if(lDstLength > 0) { //===========================================
// Convert the new data to Variant
//===========================================
map.MapAndConvertOLEDBTypeToCIMType((USHORT)dwDstType,pTemp,lDstLength,*pvarData,dwCIMType); hr = m_pInstance->SetProperty(strProp,pvarData); } cvarData.Clear(); } } else { ulErrorCount++; col.dwStatus = dwDstStatus; }
SAFE_DELETE_PTR(pDst);
} SysFreeString(strProp); }
//===================================================================
// We report any lossy conversions with a special status.
// Note that DB_S_ERRORSOCCURED is a success, rather than failure.
//===================================================================
if ( SUCCEEDED(hr) ) { hr = ( ulErrorCount ? DB_S_ERRORSOCCURRED : S_OK ); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Get the rowdata and put it into the buffer pointed by the second parameter
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetRowData(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[]) { ULONG ulErrorCount = 0; HRESULT hr = S_OK;
//=========================================================
// Navigate through every element in the array, get
// the value of the columns
//=========================================================
for (ULONG_PTR lIndex = 0 ; lIndex < cColumns ; lIndex++) { hr = GetColumnData(rgColumns[lIndex]); if ( hr != S_OK ) { ulErrorCount++; hr = S_OK; } }
if ( SUCCEEDED(hr) ) { hr = ( ulErrorCount ? DB_S_ERRORSOCCURRED : S_OK ); }
if( ulErrorCount >= cColumns) { hr = E_FAIL; }
return hr;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Set the the values of the different columns. This is called when row is created directly
// and not from rowset
/////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::SetRowData(DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[]) { ULONG ulErrorCount = 0; HRESULT hr = S_OK;
//=========================================================
// Navigate through every element in the array, set
// the value of the columns
//=========================================================
for (ULONG_PTR lIndex = 0 ; lIndex < cColumns ; lIndex++) { hr = SetColumnData(rgColumns[lIndex]); if ( hr != S_OK ) { ulErrorCount++; hr = S_OK; } }
if(SUCCEEDED(hr)) { //==============================================
// call this function to update the instance
//==============================================
hr = m_pMap->UpdateInstance(m_pInstance,FALSE); }
if ( SUCCEEDED(hr) ) { hr = ( ulErrorCount ? DB_S_ERRORSOCCURRED : S_OK ); }
if( ulErrorCount >= cColumns) { hr = E_FAIL; }
return hr;
}
//////////////////////////////////////////////////////////////////////////////////////
// Open a rowset on a column which represents qualifiers or embeded classes
// NTRaid:111833
// 06/07/00
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::OpenChild(IUnknown *pUnkOuter,WCHAR *strColName ,REFIID riid, IUnknown **ppUnk,BOOL bIsChildRowset) { HRESULT hr = S_OK;
ULONG cPropSets = 1; // NTRaid:111833
// 06/13/00
DBPROPSET* prgPropertySets = NULL; DBPROPIDSET rgPropIDSet[1]; VARIANT varValue; VariantInit(&varValue);
rgPropIDSet[0].cPropertyIDs = 0; rgPropIDSet[0].guidPropertySet = DBPROPSET_ROWSET;
//==============================================================================
// Get the properties set thru IDBBinderProperties
//==============================================================================
if(SUCCEEDED(hr = m_pUtilProp->GetProperties(PROPSET_ROWSET,0,rgPropIDSet, &cPropSets,&prgPropertySets))) { //==============================================================================
// If the column refers to a rowset ( pointing to a qualifier) get the rowset
//==============================================================================
if(bIsChildRowset) { hr = GetChildRowet(pUnkOuter,strColName ,prgPropertySets,cPropSets,riid,ppUnk); } //======================
// else get a row
//======================
else { hr = GetChildRow(pUnkOuter,strColName ,prgPropertySets,cPropSets,riid,ppUnk); } } //==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets); return hr; }
///////////////////////////////////////////////////////////////
// Function to parse the column name to get the property name
// The returned pointer is to released by the caller
///////////////////////////////////////////////////////////////
WCHAR * CRow::GetPropertyNameFromColName(WCHAR *pColName) { WCHAR *pQualiferSuffix = NULL; WCHAR *pPropName = NULL;
try { pQualiferSuffix = new WCHAR[wcslen(SEPARATOR) + wcslen(QUALIFIER_) + 1]; } catch(...) { SAFE_DELETE_ARRAY(pQualiferSuffix); throw; } if(pQualiferSuffix) { swprintf(pQualiferSuffix,L"%s%s",SEPARATOR,QUALIFIER_); if( wcsstr(pColName,pQualiferSuffix)) { int nPropLen = wcslen(pColName) - wcslen(pQualiferSuffix) +1; pPropName = new WCHAR [nPropLen];
//NTRaid:111767 & NTRaid:111768
// 06/07/00
if(pPropName) { memset(pPropName,0,nPropLen * sizeof(WCHAR)); memcpy(pPropName,pColName , (nPropLen-1) * sizeof(WCHAR)); } } SAFE_DELETE_ARRAY(pQualiferSuffix); } return pPropName; }
//////////////////////////////////////////////////////////////////////////////////////
// Function which get the embeded instance given the URL of the instance
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetEmbededInstancePtrAndSetMapClass(CURLParser *urlParser) { BSTR strPath; BSTR strProperty; int nIndex = 0; DWORD dwFlags = 0; WCHAR * strTableName; HRESULT hr = S_OK;
urlParser->GetPath(strPath); urlParser->GetEmbededInstInfo(strProperty,nIndex);
m_pInstance = (CWbemClassInstanceWrapper *)m_pMap->GetEmbededInstance(strPath,strProperty,nIndex);
if( m_pInstance == NULL) { hr = E_FAIL; } else { //==================================================
// Set the class name of the wmioledbmap function
//==================================================
strTableName = m_pInstance->GetClassName(); hr = m_pMap->SetClass(strTableName); delete [] strTableName;
SysFreeString(strPath); SysFreeString(strProperty); }
return hr; }
//////////////////////////////////////////////////////////////////////////////////////
// Function to get a child row of the particular row which is pointed by a particular
// column
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetChildRow( IUnknown *pUnkOuter, WCHAR *strColName, DBPROPSET *prgPropertySets, ULONG cPropSets, REFIID riid, IUnknown **ppUnk) { HRESULT hr = S_OK; BSTR strPath,strTable , strURL; CURLParser urlParser; DBCOLUMNACCESS col; CRow *pChildRow = NULL;
memset(&col,0,sizeof(DBCOLUMNACCESS)); col.pData = &strURL; col.columnid.eKind = DBKIND_NAME; col.columnid.uName.pwszName = strColName; ; col.wType = DBTYPE_BSTR;
if(SUCCEEDED(hr = GetColumnData(col))) { urlParser.SetURL(strURL); urlParser.GetClassName(strTable); hr = urlParser.GetPathWithEmbededInstInfo(strPath);
try { pChildRow = new CRow(pUnkOuter, m_pCreator); } catch(...) { SAFE_DELETE_PTR(pChildRow); throw; }
if(SUCCEEDED(hr) && SUCCEEDED(hr = pChildRow->InitRow(strPath, strTable))) { hr = pChildRow->QueryInterface(riid, (void **)ppUnk); } SysFreeString(strTable); SysFreeString(strPath); }
if(FAILED(hr)) { SAFE_DELETE_PTR(pChildRow); }
return hr; }
//////////////////////////////////////////////////////////////////////////////////////
// Function to get a child rowset of the particular row which is pointed by a particular
// column
//////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetChildRowet(IUnknown *pUnkOuter, WCHAR *strColName, DBPROPSET *prgPropertySets, ULONG cPropSets, REFIID riid, IUnknown **ppUnk) {
HRESULT hr = S_OK; CRowset *pChildRowset = NULL; int iOrdinal = 0; WCHAR *pPropName = NULL; ULONG lRsType = 0;
lRsType = m_pMap->ParseQualifiedNameToGetColumnType(strColName);
if(lRsType == WMI_PROPERTY_QUALIFIER) { //=============================================================
// Get the name of the property for which the qualifiers are
// to be retrieved as rowset
//=============================================================
pPropName = GetPropertyNameFromColName(strColName); lRsType = PROPERTYQUALIFIER; } else if(lRsType == WMI_CLASS_QUALIFIER) { lRsType = CLASSQUALIFIER; }
if((pPropName != NULL && lRsType == PROPERTYQUALIFIER) || lRsType == CLASSQUALIFIER) { try { //================================
// Create a new rowset
//================================
pChildRowset = new CRowset(pUnkOuter,lRsType, pPropName,m_pCreator,m_pMap); } catch(...) { SAFE_DELETE_PTR(pChildRowset); throw; } // Initialize the rowset
if( pChildRowset) if(S_OK == (hr = pChildRowset->InitRowsetForRow(pUnkOuter,cPropSets,prgPropertySets,m_pInstance))) { hr = pChildRowset->QueryInterface(riid , (void **)ppUnk); }
SAFE_DELETE_ARRAY(pPropName); } else { hr = DB_E_BADCOLUMNID; }
return hr;
}
////////////////////////////////////////////////////////////////////////////////////////
// Creates a new instance
// called from ICreateRow::CreateRow
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::CreateNewRow(CWbemClassInstanceWrapper **pNewInst) {
return m_pMap->AddNewInstance((CWbemClassWrapper **)pNewInst);
}
////////////////////////////////////////////////////////////////////////////////////////
// Function which gets all the key values from the URL and updates it to
// the new instance
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::UpdateKeysForNewInstance() { HRESULT hr = S_OK; DBCOLUMNACCESS dbCol; SAFEARRAY *psaKeyPropNames; LONG lBound = 0 , uBound = 0; BSTR strProperty; LONG rgIndices[1]; CURLParser urlParser; VARIANT varKeyValue; CWbemClassWrapper * pTempInstance = NULL;
VariantInit(&varKeyValue);
urlParser.SetPath(m_strKey);
memset(&dbCol,0,sizeof(DBCOLUMNACCESS));
dbCol.columnid.eKind = DBKIND_NAME; dbCol.columnid.uName.pwszName = NULL; dbCol.cbDataLen = -1; dbCol.wType = DBTYPE_VARIANT | DBTYPE_BYREF;
// Get the propertynames of the key values
hr = m_pMap->GetKeyPropertyNames(&psaKeyPropNames);
// Get the bounds of the array returned
hr = SafeArrayGetLBound(psaKeyPropNames,1,&lBound); hr = SafeArrayGetUBound(psaKeyPropNames,1,&uBound);
// Navigate thru every element of the array
for( int nIndex = lBound ; nIndex <= uBound ; nIndex++) { rgIndices[0] = nIndex; hr = SafeArrayGetElement(psaKeyPropNames,&rgIndices[0],(void *)&strProperty);
// Get the value of the key from the URL
if(SUCCEEDED(hr = urlParser.GetKeyValue(strProperty,varKeyValue))) {
dbCol.columnid.uName.pwszName = (WCHAR *)strProperty; dbCol.pData = &varKeyValue;
hr = SetColumnData(dbCol,TRUE);
VariantClear(&varKeyValue);
if(hr != S_OK) { break; } } }
// Destroy the array created
SafeArrayDestroy(psaKeyPropNames);
if(SUCCEEDED(hr)) { // call this function to save the new instance
hr = m_pMap->UpdateInstance(m_pInstance,TRUE); }
// The instance may be created, but we have to
// check if the URL passed identifies the row , if no
// then return error
if( hr == S_OK) { // Convert it into upper case
pTempInstance = m_pMap->GetInstance(m_strKey); if(pTempInstance == NULL) { hr = DB_E_NOTFOUND; } else { m_pInstance = (CWbemClassInstanceWrapper *)pTempInstance; } }
// Delete the instance created if there
// any failure in the process of creating new instance
if(FAILED(hr)) { m_pMap->DeleteInstance(m_pInstance); m_pInstance = NULL; hr = DB_E_NOTFOUND; }
return hr; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to open a row pointed by the URL
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::OpenRow(LPCOLESTR pwszURL,IUnknown * pUnkOuter,REFIID riid,IUnknown** ppOut) { HRESULT hr = S_OK; LONG lObjType = -1; CRow * pRow = NULL; CURLParser urlParser; CBSTR bstrTemp; CBSTR bstrPath; CBSTR bstrClassName;
bstrTemp.SetStr((LPWSTR)pwszURL); urlParser.SetURL((BSTR)bstrTemp); lObjType = urlParser.GetURLType();
switch(lObjType) { case URL_ROW: { urlParser.GetPath((BSTR &)bstrPath); urlParser.GetClassName((BSTR &)bstrClassName); } break;
case -1 : { hr = DB_E_NOTFOUND; break; }
default: { urlParser.GetPath((BSTR &)bstrPath); break; }
}
if(SUCCEEDED(hr)) { try { pRow = new CRow(pUnkOuter,m_pCreator); } catch(...) { SAFE_DELETE_PTR(pRow); }
if(SUCCEEDED(hr)) { hr = pRow->InitRow(bstrPath,bstrClassName,GetQualifierFlags(),ROWOPEN); }
if(SUCCEEDED(hr)) { DBPROPSET* prgPropertySets; DBPROPIDSET rgPropIDSet[1]; ULONG cPropSets = 1;
rgPropIDSet[0].cPropertyIDs = 0; rgPropIDSet[0].guidPropertySet = DBPROPSET_ROWSET; //==============================================================================
// Get the properties set thru of the current row and set it on the rowset
//==============================================================================
if(SUCCEEDED(hr = m_pUtilProp->GetProperties(PROPSET_ROWSET,0,rgPropIDSet, &cPropSets,&prgPropertySets))) { hr = pRow->SetRowProperties(cPropSets,prgPropertySets); } //==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProp->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets);
if(FAILED(hr = pRow->QueryInterface(riid,(void **)ppOut))) { SAFE_DELETE_PTR(pRow); *ppOut = NULL; } } }
return hr; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to open a rowset which contains instance of container/scope
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::OpenRowset(LPCOLESTR pwszURL, IUnknown * pUnkOuter, REFIID riid, BOOL bContainer, IUnknown** ppOut, ULONG cPropertySets, DBPROPSET __RPC_FAR rgPropertySets[]) { HRESULT hr = S_OK; WCHAR * pstrPath = NULL; ULONG cPropSets = 1; CRowset * pRowset = NULL; DBPROPIDSET rgPropIDSet[1]; VARIANT varValue; VariantInit(&varValue); WCHAR * pstrTemp = NULL; WCHAR * pStrRelPath = NULL; LPWSTR pStrObjectToOpen = NULL;
rgPropIDSet[0].cPropertyIDs = 0; rgPropIDSet[0].guidPropertySet = DBPROPSET_ROWSET;
pRowset = new CRowset(pUnkOuter,m_pCreator,m_pCon); if(!pRowset) { hr = E_OUTOFMEMORY; }
if(SUCCEEDED(hr)) { INSTANCELISTTYPE ObjInstListType = GetObjectTypeProp(cPropertySets, rgPropertySets); WCHAR * pStrPath = NULL; CURLParser urlParser; CBSTR bstrTemp; if(!bContainer) { // Get the relative path of the current object
if(SUCCEEDED(hr = m_pMap->GetRelativePath(m_pInstance,pStrRelPath))) { //===========================================
// If URL is passed open rowset on the URL
//===========================================
if(pwszURL == NULL) { pstrTemp = pStrRelPath; } //===========================================
// else get URL of the current row
//===========================================
else { pstrTemp = new WCHAR[wcslen(pStrRelPath) + wcslen(pwszURL) + wcslen(PATHSEPARATOR) + 1]; if(pstrTemp) { wcscpy(pstrTemp,pStrRelPath); wcscat(pstrTemp,PATHSEPARATOR); wcscat(pstrTemp,pwszURL); SAFE_DELETE_ARRAY(pStrRelPath); pStrRelPath = pstrTemp; } else { hr = E_OUTOFMEMORY; } } } } else { CBSTR strObjPath; VARIANT varDataSource; VariantInit(&varDataSource);
if(m_pCon) { if(SUCCEEDED(hr = m_pCon->GetNodeName(varDataSource.bstrVal))) { varDataSource.vt = VT_BSTR; } } else {
if(SUCCEEDED(hr = m_pCreator->GetDataSrcProperty(DBPROP_INIT_DATASOURCE,varDataSource)) && varDataSource.vt == VT_BSTR && varDataSource.bstrVal != NULL ) { hr = S_OK; } else { hr = E_UNEXPECTED; } }
if(SUCCEEDED(hr)) { m_pMap->GetInstanceKey(m_pInstance,strObjPath); if(strObjPath != NULL && _wcsicmp(strObjPath,varDataSource.bstrVal) != 0) { hr = m_pMap->GetRelativePath(m_pInstance,pStrObjectToOpen); } else { pStrObjectToOpen = NULL; } } VariantClear(&varDataSource); pstrTemp = (WCHAR *)pwszURL; } /* bstrTemp.SetStr(pstrTemp);
urlParser.SetURL((BSTR)bstrTemp); bstrTemp.Clear(); urlParser.GetPath((BSTR &)bstrTemp); */ if(SUCCEEDED(hr)) { // pStrPath = new WCHAR[SysStringLen(bstrTemp) + 1];
// if(pStrPath)
{ // memset(pStrPath , 0 , (SysStringLen(bstrTemp) + 1) * sizeof(WCHAR));
// memcpy(pStrPath,bstrTemp,SysStringLen(bstrTemp) * sizeof(WCHAR));
//==========================================================================
// Call this function to open the object pointed by the URL as scope or
// container
//==========================================================================
hr = pRowset->InitRowset(cPropertySets,rgPropertySets,pstrTemp,pStrObjectToOpen,ObjInstListType);
SAFE_DELETE_ARRAY(pStrPath); } /* else
{ hr = E_OUTOFMEMORY; } */ } }
if(SUCCEEDED(hr)) { if(FAILED(hr = pRowset->QueryInterface(riid,(void **)ppOut))) { SAFE_DELETE_PTR(pRowset); *ppOut = NULL; } } else { SAFE_DELETE_PTR(pRowset); *ppOut = NULL; }
SAFE_DELETE_ARRAY(pStrObjectToOpen); SAFE_DELETE_ARRAY(pStrRelPath); return hr; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to set properties of the row
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::SetRowProperties(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(); }
return hr; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to delete/unlink objects from scope/container
// Object will be deleted if the current object is opened as scope
// object will be unlinked from the current object is opened as container
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::Delete(LPCOLESTR lpszURL,DWORD dwDeleteFlags,DBSTATUS &dbStatus) { HRESULT hr = S_OK; BOOL bContainer = FALSE; CURLParser urlParser; CBSTR strTemp; dbStatus = DBSTATUS_S_OK;
strTemp.SetStr((LPWSTR)lpszURL);
urlParser.SetURL(strTemp);
strTemp.Unbind(); strTemp.Clear();
urlParser.GetPath((BSTR &)strTemp); bContainer = IsContainer(); if(bContainer) { CBSTR strContainer; strContainer.SetStr(m_strKey); //==============================================================
// call this function to unlink object pointed by strTemp
// from object pointed by m_strPath acting as container
//==============================================================
if(FAILED(hr = m_pMap->UnlinkObjectFromContainer(strContainer,strTemp))) { dbStatus = DBSTATUS_E_UNAVAILABLE; }
} else { //==============================================================
// Get the instance pointed by the path and then
// delete the object
//==============================================================
CWbemClassWrapper *pInstToDelete = NULL; pInstToDelete = m_pMap->GetInstance(strTemp); if(pInstToDelete) { hr = m_pMap->DeleteInstance(pInstToDelete); } else { dbStatus = DBSTATUS_E_UNAVAILABLE; } } // else
return hr; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to move object from one container to another
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::MoveObjects(WCHAR * pStrDstURL,WCHAR * pstrSrcURL, WCHAR *& pNewURL,DBSTATUS &dbStatus) { HRESULT hr = S_OK; BOOL bContainer = FALSE; CBSTR strSrcObj,strDstObj;
dbStatus = DBSTATUS_S_OK;
//============================================================
// Get the Path string for source and destination objects
//============================================================
strSrcObj.SetStr(pstrSrcURL); if(GetPathFromURL((BSTR &)strSrcObj)) { strDstObj.SetStr(pStrDstURL); if(GetPathFromURL((BSTR &)strDstObj)) { hr = E_FAIL; dbStatus = DBSTATUS_E_INVALIDURL; } } else { hr = E_FAIL; dbStatus = DBSTATUS_E_INVALIDURL; }
if(SUCCEEDED(hr)) { CBSTR strContainer; strContainer.SetStr(m_strKey);
//==============================================================
// call this function to unlink object pointed by strSrcObj
// from object pointed by m_strPath acting as container
//==============================================================
if(FAILED(hr = m_pMap->UnlinkObjectFromContainer(strContainer,strSrcObj))) { dbStatus = DBSTATUS_E_UNAVAILABLE; } else //==============================================================
// call this function to link object pointed by strSrcObj
// to object pointed by strDstObj acting as container
//==============================================================
if(FAILED(hr = m_pMap->LinkObjectFromContainer(strDstObj,strSrcObj))) { dbStatus = DBSTATUS_E_UNAVAILABLE; } try { pNewURL = new WCHAR[wcslen(pstrSrcURL) +1]; } catch(...) { SAFE_DELETE_ARRAY(pNewURL); throw; } if(pNewURL) { //==============================================================
// URL of the object does not change as this is just a move of
// object from one container to another
//==============================================================
wcscpy(pNewURL,pstrSrcURL); } else { hr = E_OUTOFMEMORY; } } // If succeeded(hr)
return hr; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to get Path from URL string
////////////////////////////////////////////////////////////////////////////////////////
BOOL CRow::GetPathFromURL(BSTR &str) { BOOL bRet = FALSE; CURLParser urlParser;
if(SUCCEEDED( urlParser.SetURL(str))) { SysFreeString(str); urlParser.GetPath(str); bRet = TRUE; }
return bRet; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to check if the current object is to be considered as Scope/Container
////////////////////////////////////////////////////////////////////////////////////////
BOOL CRow::IsContainer() { VARIANT vValue; BOOL bRet = FALSE; VariantInit(&vValue);
if(SUCCEEDED(GetRowsetProperty(DBPROP_WMIOLEDB_OBJECTTYPE,vValue))) { bRet = (V_I4(&vValue) == DBPROPVAL_CONTAINEROBJ) ? TRUE : FALSE; }
return bRet; }
////////////////////////////////////////////////////////////////////////////////////////
// Function to move object from one container to another
////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::CopyObjects(WCHAR * pStrDstURL,WCHAR * pstrSrcURL, WCHAR *& pNewURL,DBSTATUS &dbStatus) { HRESULT hr = S_OK; BOOL bContainer = FALSE; CBSTR strSrcObj,strDstObj;
dbStatus = DBSTATUS_S_OK;
//============================================================
// Get the Path string for source and destination objects
//============================================================
strSrcObj.SetStr(pstrSrcURL); if(GetPathFromURL((BSTR &)strSrcObj)) { strDstObj.SetStr(pStrDstURL); if(GetPathFromURL((BSTR &)strDstObj)) { hr = E_FAIL; dbStatus = DBSTATUS_E_INVALIDURL; } } else { hr = E_FAIL; dbStatus = DBSTATUS_E_INVALIDURL; }
if(SUCCEEDED(hr)) { WCHAR * pstrNewPath = NULL; if(IsContainer()) { //==============================================================
// call this function to link object pointed by strSrcObj
// to object pointed by strDstObj acting as container
//==============================================================
hr = m_pMap->LinkObjectFromContainer(strDstObj,strSrcObj); pstrNewPath = pstrSrcURL; } else { // Memory for pstrNewPath will be allocated in this function
hr = m_pMap->CloneAndAddNewObjectInScope(strSrcObj,strDstObj,pstrNewPath); } if(FAILED(hr)) { dbStatus = DBSTATUS_E_UNAVAILABLE; } try { pNewURL = new WCHAR[wcslen(pstrSrcURL) +1]; } catch(...) { SAFE_DELETE_ARRAY(pNewURL); if(!IsContainer()) { SAFE_DELETE_ARRAY(pstrNewPath); } throw; } if(pNewURL) { //==============================================================
// URL of the object does not change as this is just a move of
// object from one container to another
//==============================================================
wcscpy(pNewURL,pstrSrcURL);
} else { hr = E_OUTOFMEMORY; }
if(!IsContainer()) { SAFE_DELETE_ARRAY(pstrNewPath); }
} // If succeeded(hr)
return hr; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to fetch IUnknown properties
// NTRaid:135384
////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CRow::GetIUnknownColumnValue(DBORDINAL iCol,REFIID riid,IUnknown ** ppUnk,LPCWSTR pStrColName) { ROWBUFF * pRowBuff = NULL; COLUMNDATA * pColumnData = NULL; void * pSrc = NULL; BSTR strProp = NULL; DBTYPE dwDataType = 0; BYTE * pTemp = NULL; DBLENGTH uDatLength = 0; DWORD dwFlags = 0; HRESULT hr = S_OK; BOOL bGetData = TRUE;
*ppUnk = NULL; if(m_pSourcesRowset) { // if the column is part of the parent rowset then get data from the parent rowset's buffer
if(iCol == m_pSourcesRowset->GetOrdinalFromColName((WCHAR *)pStrColName)) { // Set this flag that data to be retrieved is identified
bGetData = FALSE; //=========================================================
// if data is not yet received then fetch the data
//=========================================================
if(S_OK != m_pSourcesRowset->IsSlotSet(m_hRow)) { hr = m_pSourcesRowset->GetData(m_hRow); } if( (m_pSourcesRowset->m_ulProps & OTHERUPDATEDELETE) &&(m_pSourcesRowset->m_ulLastFetchedRow != m_hRow)) { if(SUCCEEDED(hr = m_pSourcesRowset->GetDataToLocalBuffer(m_hRow))) { m_pSourcesRowset->m_ulLastFetchedRow = m_hRow; } }
pRowBuff = m_pSourcesRowset->GetRowBuff(m_hRow , TRUE); pColumnData = (COLUMNDATA *) ((BYTE *) pRowBuff + m_pSourcesRowset->m_Columns.GetDataOffset(iCol));
pSrc = (pColumnData->pbData); if(pSrc != NULL) { hr = (*(IUnknown **)pSrc)->QueryInterface(riid,(void **)ppUnk); } } } if(bGetData) { strProp = Wmioledb_SysAllocString(pStrColName); hr = m_pMap->GetProperty(m_pInstance,strProp, pTemp,dwDataType ,uDatLength, dwFlags ); if(SUCCEEDED(hr) && dwDataType == DBTYPE_IUNKNOWN && pTemp != NULL) { hr = (*(IUnknown **)pTemp)->QueryInterface(riid,(void **)ppUnk); } SAFE_FREE_SYSSTRING(strProp);
}
return hr;
}
|