|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Microsoft WMI OLE DB Provider
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
//
// COMMAND.CPP - CCommand object implementation
// File also contain the implementation of CQuery class
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "headers.h"
#include "command.h"
#define NO_ROWCOUNT_TOTAL (-1)
#define PARAM_LIST_SIZE 2056
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma warning (disable:4355)
CCommand::CCommand( CDBSession* pCDBSession, LPUNKNOWN pUnkOuter ) : CBaseObj(BOT_COMMAND,pUnkOuter) { //===============================================================
// Initially, NULL all contained interfaces
//===============================================================
m_pIAccessor = NULL; m_pIColumnsInfo = NULL; m_pIConvertType = NULL;
//=======================================================
// Establish the parent object
//=======================================================
m_pCDBSession = pCDBSession; m_pCDBSession->GetOuterUnknown()->AddRef();
//=======================================================
// Initialize all ptrs to embedded interfaces
//=======================================================
m_pICommandText = NULL; m_pICommandWithParameters = NULL; m_pICommandProperties = NULL; m_pISupportErrorInfo = NULL;
//=======================================================
// Initialize simple member vars
//=======================================================
m_cRowsetsOpen = 0; m_guidImpersonate = GUID_NULL; // m_pdbc = pCDBSession->GetDBConnection();
m_pQuery = NULL;
m_pColumns = NULL; m_cTotalCols = 0; m_cCols = 0; m_cNestedCols = 0;
} #pragma warning (default:4355)
////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Destructor for this class
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
CCommand::~CCommand (void) { SAFE_DELETE_PTR( m_pUtilProps); SAFE_DELETE_PTR( m_pQuery ); //====================================================================
// Free Statement
//====================================================================
if (m_pQuery) { m_pQuery->InitQuery(); }
//=======================================================
// Delete the embedded pointers
//=======================================================
SAFE_DELETE_PTR( m_pICommandText ); SAFE_DELETE_PTR( m_pICommandWithParameters ); SAFE_DELETE_PTR( m_pICommandProperties ); SAFE_DELETE_PTR(m_pIAccessor); SAFE_DELETE_PTR(m_pIConvertType); SAFE_DELETE_PTR(m_pISupportErrorInfo); SAFE_DELETE_PTR(m_pIColumnsInfo);
SAFE_DELETE_PTR(m_pColumns);
//====================================================================
// Since Command Object is going away, we can decrement
// our count on the session object.
// Note that this typically deletes our hdbc, DataSource, Session.
// (So do this last.)
//====================================================================
if (m_pCDBSession) { m_pCDBSession->GetOuterUnknown()->Release(); } } ////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Initialize the command Object. This Init routine should be used by CreateCommand and also be called
// as a secondary initialization routine for the other FInit on the command object.
//
// If this initialization routine fails, it is the callers responsibility to delete this object.
// The destructor will then clean up any allocated resources
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCommand::FInit( WORD wRowsetProps ) { HRESULT hr = S_OK;
//===============================================
// Get the query class going
//===============================================
m_pQuery = new CQuery;
//===============================================
// Initialize rowset properties
//===============================================
m_pUtilProps = new CUtilProp;
// NTRaid: 136443
// 07/05/00
if(m_pUtilProps == NULL) { hr = E_OUTOFMEMORY; } else if(SUCCEEDED(hr = m_pUtilProps->FInit(COMMANDPROP))) {
//===============================================
// Initialize ErrorData
//===============================================
if (FAILED(m_CError.FInit())) hr = (E_OUTOFMEMORY); else { m_pIAccessor = new CImpIAccessor(this,FALSE); if( m_pIAccessor ){ hr = m_pIAccessor->FInit(); }
if(SUCCEEDED(hr)) { m_pICommandText = new CImpICommandText(this); m_pICommandWithParameters = new CImpICommandWithParameters(this); m_pICommandProperties = new CImpICommandProperties(this); m_pIConvertType = new CImpIConvertType(this); m_pISupportErrorInfo = new CImpISupportErrorInfo(this); m_pIColumnsInfo = new CImpIColumnsInfoCmd(this);
//===============================================
// Initialize name pool
//===============================================
m_extNamePool.FInit(1,0,256);
if( m_pUtilProps && m_pIAccessor && m_pICommandText && m_pICommandWithParameters && m_pIConvertType && m_pIColumnsInfo && m_pISupportErrorInfo) { hr = S_OK; } else { hr = E_OUTOFMEMORY; } } } }
if(SUCCEEDED(hr)) { hr = AddInterfacesForISupportErrorInfo(); }
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////////
// Function to add interfaces to ISupportErrorInfo interface
/////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCommand::AddInterfacesForISupportErrorInfo() { HRESULT hr = S_OK;
if(SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IAccessor)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_ICommand)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_ICommandText)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_ICommandProperties)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_ICommandWithParameters)) && SUCCEEDED(hr = m_pISupportErrorInfo->AddInterfaceID(IID_IColumnsInfo))) { hr = m_pISupportErrorInfo->AddInterfaceID(IID_IConvertType); }
return hr; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Determines if command is canceled and if not sets the currently active CQuery.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
inline HRESULT CCommand::CheckCanceledHelper(CQuery* pstmt) { HRESULT hr; DWORD dwCancelStatus = m_pQuery->GetCancelStatus();
// Set the currently active CQuery, for use by the cancel routine
m_pQuery->m_pcsQuery->Enter(); if (dwCancelStatus & CMD_EXEC_CANCELED){ dwCancelStatus &= ~(CMD_EXEC_CANCELED|CMD_EXEC_CANCELED_BEFORE_CQUERY_SET); hr = DB_E_CANCELED; } else{ hr = S_OK; } m_pQuery->m_pcsQuery->Leave(); return hr; } ////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Returns a pointer to a specified interface. Callers use QueryInterface to determine which interfaces
// the called object supports.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommand::QueryInterface( REFIID riid, LPVOID * ppv ) { HRESULT hr = S_OK;
if ( ppv == NULL ) { hr = E_INVALIDARG; } else { //=======================================================
// 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_ICommand || riid == IID_ICommandText) *ppv = (LPVOID)m_pICommandText; else if ( riid == IID_ICommandProperties ) *ppv = (LPVOID)m_pICommandProperties; else if ( riid == IID_IColumnsInfo ) *ppv = (LPVOID)m_pIColumnsInfo; else if ( riid == IID_ICommandWithParameters ) *ppv = (LPVOID)m_pICommandWithParameters; else if ( riid == IID_ISupportErrorInfo ) *ppv = (LPVOID)m_pISupportErrorInfo; else if ( riid == IID_IConvertType ) *ppv = (LPVOID)m_pIConvertType; else{ *ppv = NULL; hr = E_NOINTERFACE; }
if( *ppv ){ ((LPUNKNOWN)*ppv)->AddRef(); } } return hr; } ////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Increments a persistence count for the object
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CCommand::AddRef (void) { ULONG cRef = InterlockedIncrement( (long*) &m_cRef); return cRef; } ////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Decrements a persistence count for the object and if persistence count is 0, the object destroys itself.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG) CCommand::Release (void) { ULONG cRef = InterlockedDecrement( (long *) &m_cRef); if ( !cRef ){ delete this; return 0; } return cRef; }
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
// UTILITY FUNCTIONS UTILITY FUNCTIONS
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Errors that can occur may result in another HRESULT other than E_FAIL, thus this routine
// determines that HRESULT and posts the errors
//
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCommand::PostExecuteWarnings( CErrorData* pError, const IID* piid ) { HRESULT hr = S_OK;
if (*piid == IID_ITableDefinition){
} if (*piid == IID_IIndexDefinition){ } //==========================================================
// If we are not posting errors for IID_IOpenRowset
//==========================================================
if (*piid == IID_IOpenRowset){ //======================================================
// Map errors in command to DB_E_NOTABLE.
// Other errors should flow through. (Some like
// _DATAOVERFLOW we should never get.)
//======================================================
if (hr == DB_E_ERRORSINCOMMAND) { hr = (DB_E_NOTABLE); } else if (hr == DB_E_ABORTLIMITREACHED || hr == DB_E_CANCELED) { hr = (E_FAIL); } } g_pCError->PostWMIErrors(hr, piid, pError); return hr; }
////////////////////////////////////////////////////////////////////////////////////////////////
//
// Errors that can occur may result in another HRESULT other than E_FAIL, thus this routine
// determines that HRESULT and posts the errors
//
////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCommand::PostExecuteErrors( CErrorData* pError, const IID* piid ) { HRESULT hr = S_OK;
if (*piid == IID_ITableDefinition){
} if (*piid == IID_IIndexDefinition){ } //==========================================================
// If we are not posting errors for IID_IOpenRowset
//==========================================================
if (*piid == IID_IOpenRowset){ //======================================================
// Map errors in command to DB_E_NOTABLE.
// Other errors should flow through. (Some like
// _DATAOVERFLOW we should never get.)
//======================================================
if (hr == DB_E_ERRORSINCOMMAND) { hr = (DB_E_NOTABLE); } else if (hr == DB_E_ABORTLIMITREACHED || hr == DB_E_CANCELED) { hr = (E_FAIL); } } g_pCError->PostWMIErrors(hr, piid, pError); return hr; }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Marks command as unprepared, and may force this state.
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommand::UnprepareHelper( DWORD dwUnprepareType ) {
// Unprepare the statement - free it from WBEM
// Free memory for the row metadata for the first rowset in the command.
// m_extNamePool.Free();
DWORD dwStatus = m_pQuery->GetStatus(); dwStatus &= ~CMD_HAVE_COLUMNINFO;
if (UNPREPARE_NEW_CMD == dwUnprepareType) // A new command is being set
{ // We need to remember that we have to rebuild our parameter info
dwStatus &= ~(CMD_TEXT_PARSED | CMD_READY | CMD_PARAMS_USED | CMD_EXECUTED_ONCE );
// Reset parameter information.
if (m_pQuery->GetParamCount()){ if (m_pQuery->m_prgbCallParams){ delete [] m_pQuery->m_prgbCallParams; m_pQuery->m_prgbCallParams = NULL; } if (m_pQuery->m_prgProviderParamInfo){ delete [] m_pQuery->m_prgProviderParamInfo; m_pQuery->m_prgProviderParamInfo = NULL; } //@devnote We do not delete the consumer parameter information.
// The only reference in the OLE DB spec to removing the consumer
// parameter info is via ICommandWithParameters::SetParameterInfo.
} } else if (UNPREPARE_RESET_CMD == dwUnprepareType){ dwStatus &= ~CMD_READY; }
m_pQuery->InitStatus(dwStatus); return S_OK; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Determines if bookmarks are present.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CCommand::FHaveBookmarks() { BOOL flag = FALSE;
// flag = (m_pUtilProps.IsRequiredTrue(CUtilProp::eid_DBPROPSET_ROWSET, CUtilProp::eid_DBPROPVAL_BOOKMARKS)
// || m_pUtilProps.IsRequiredTrue(CUtilProp::eid_DBPROPSET_ROWSET, CUtilProp::eid_DBPROPVAL_IRowsetLocate)
// || m_pUtilProps.IsRequiredTrue(CUtilProp::eid_DBPROPSET_ROWSET, CUtilProp::eid_DBPROPVAL_CANHOLDROWS) );
return flag; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Re-executes a command to reposition to reposition to the beginning of the rowset.
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCommand::ReExecute( PCROWSET pCRowset,LONG* pcCursorRows, WORD* pcCols ) { DWORD dwFlags = EXECUTE_RESTART; // return ExecuteHelper(&IID_IRowset, pCRowset->GetStmt(), &dwFlags, pCRowset->GetRowsetProps(), NULL, NULL, pcCursorRows, pcCols, NULL);
return S_OK; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////
STDMETHODIMP CCommand::Execute( IUnknown* pUnkOuter, //@parm IN | Outer Unknown
REFIID riid, //@parm IN | Interface ID of the interface being queried for.
DBPARAMS* pParams, //@parm INOUT | Parameter Array
DBROWCOUNT* pcRowsAffected, //@parm OUT | count of rows affected by command
IUnknown** ppRowsets //@parm OUT | Pointer to interface that was instantiated
) { HRESULT hr = S_OK; HRESULT hrProp = S_OK; DWORD dwFlags = 0; CRowset* pCRowset = NULL; DWORD dwStatus = 0; LPWSTR pwstrWQL = NULL; ULONG cwchWQL = 0; const IID* pIID = &IID_ICommand; CUtilProp* pRowsetProps = NULL; CUtlParam *pCUtlParam = NULL; LONG cCursorCount = 0;
//==========================================================================
// Initialize Return Buffers
//==========================================================================
if ( ppRowsets ) { *ppRowsets = NULL; } if ( pcRowsAffected ) { *pcRowsAffected = NO_ROWCOUNT_TOTAL; }
//==========================================================================
// If the IID asked for is IID_NULL, then we can expect that this is a
// non-row returning statement
//==========================================================================
if (riid == IID_NULL) { dwFlags |= EXECUTE_NOROWSET; } //==========================================================================
// Check to see if IID_IOpenRowset is calling Execute to open a rowset.
//==========================================================================
if (m_guidImpersonate != GUID_NULL) { pIID = &m_guidImpersonate; } //==========================================================================
// Check Arguments - Only check on row returning statements
//==========================================================================
if (!(dwFlags & EXECUTE_NOROWSET) && (ppRowsets == NULL)) { hr = E_INVALIDARG; // return g_pCError->PostHResult((E_INVALIDARG), pIID);
} else //==========================================================================
// At least 1 ParamSet and pData is null
//==========================================================================
if (pParams && (pParams->cParamSets > 0) && (NULL == pParams->pData)) { hr = E_INVALIDARG; // return g_pCError->PostHResult((E_INVALIDARG), pIID);
} else //==========================================================================
// Check that a command has been set
//==========================================================================
if(!(m_pQuery->GetStatus() & CMD_TEXT_SET)) { hr = DB_E_NOCOMMAND; // return g_pCError->PostHResult((DB_E_NOCOMMAND), pIID);
} else //==========================================================================
// The outer object must explicitly ask for IUnknown
//==========================================================================
if (pUnkOuter != NULL && riid != IID_IUnknown) { hr = DB_E_NOAGGREGATION; // return g_pCError->PostHResult((DB_E_NOAGGREGATION), pIID);
} else { //==========================================================================
// If there are parameters
//==========================================================================
if (pParams){ //======================================================================
// Build the bind information
//======================================================================
pCUtlParam = new CUtlParam; if (NULL == pCUtlParam){ hr = E_OUTOFMEMORY; // hr = g_pCError->PostHResult((E_OUTOFMEMORY), pIID);
} else { pCUtlParam->AddRef(); hr = pCUtlParam->BuildBindInfo(this, pParams, pIID); /* if (SUCCEEDED(hr = pCUtlParam->BuildBindInfo(this, pParams, pIID)))
{ m_pQuery->SetType(METHOD_ROWSET); }
*/ } }
if( SUCCEEDED(hr)) { if (!(m_pQuery->GetStatus() & CMD_EXECUTED_ONCE)){ //======================================================================
// Set the parameter binding information for the statement
//======================================================================
if (pCUtlParam) { m_pQuery->SetBindInfo(pCUtlParam); } //======================================================================
// If command not prepared, prepare it now
//======================================================================
m_pQuery->SetStatus(CMD_READY); }
//==========================================================================
// For Row Returning statements, we need to make a copy of the
// command object's Property object to hand off to the Rowset Object
//==========================================================================
if ( !(dwFlags & EXECUTE_NOROWSET) ){
pCRowset = new CRowset(pUnkOuter,m_pCDBSession); if (pCRowset == NULL){ hr = E_OUTOFMEMORY; // hr = g_pCError->PostHResult((E_OUTOFMEMORY), pIID);
} else { //=========================================================================
// We need to take a reference count on the pCRowset Ptr so if a
// called method calls Addref and then Release on this
// pointer, we do not go back to zero and delete ourselve.
//=========================================================================
pCRowset->AddRef();
/*
//=========================================================================
// AddRef Session Object
//=========================================================================
if (m_pCDBSession) m_pCDBSession->AddRef(); // AddRef is not required as the Rowset Constuctor
// does the AddRef on the passed session
*/
if (IID_ICommand == *pIID){
//=====================================================================
// AddRef ourself (as Parent)
//=====================================================================
// GetOuterUnknown()->AddRef();
} else{ //=====================================================================
// AddRef Session Object (as Parent)
//=====================================================================
if (m_pCDBSession) { m_pCDBSession->GetOuterUnknown()->AddRef(); } } //=========================================================================
// AddRef ourself (as Command)
//=========================================================================
//AddRef();
//=========================================================================
// Do initialization.
//=========================================================================
ULONG cPropSets = 0; DBPROPSET* prgPropertySets = NULL; DBPROPIDSET rgPropIDSet[2]; DBPROPID rgPropId[1];
memset(rgPropIDSet,0,2 * sizeof(DBPROPIDSET)); // Get the property DBPROP_WMIOLEDB_ISMETHOD
rgPropId[0] = DBPROP_WMIOLEDB_ISMETHOD; rgPropIDSet[0].cPropertyIDs = 1; rgPropIDSet[0].guidPropertySet = DBPROPSET_WMIOLEDB_ROWSET; rgPropIDSet[0].rgPropertyIDs = rgPropId;
// if this property is true then set the command type to METHOD
if(SUCCEEDED(hr = m_pUtilProps->GetProperties(PROPSET_COMMAND,1,rgPropIDSet, &cPropSets,&prgPropertySets))) { if(prgPropertySets->rgProperties->vValue.boolVal == VARIANT_TRUE) { m_pQuery->SetType(METHOD_ROWSET); } else { m_pQuery->SetType(COMMAND_ROWSET); } }
hr = S_OK;
//==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProps->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets);
memset(rgPropIDSet,0,2 * sizeof(DBPROPIDSET));
// NTRaid: 135246
// Getting only the rowset properties
rgPropIDSet[0].cPropertyIDs = 0; rgPropIDSet[0].guidPropertySet = DBPROPSET_ROWSET; rgPropIDSet[0].rgPropertyIDs = NULL;
rgPropIDSet[1].cPropertyIDs = 0; rgPropIDSet[1].guidPropertySet = DBPROPSET_WMIOLEDB_ROWSET; rgPropIDSet[1].rgPropertyIDs = NULL;
//=========================================================================
// Get the properties- get the rowset properties
//=========================================================================
hr = m_pUtilProps->GetProperties(PROPSET_ROWSET,2,rgPropIDSet, &cPropSets,&prgPropertySets); if( hr == S_OK ){
hr = pCRowset->InitRowset(cPropSets, prgPropertySets,-1,m_pQuery , this ); if ( FAILED(hr) ){ g_pCError->PostHResult(hr, pIID); *ppRowsets = NULL; }
} else{ if ( FAILED(hr) ){ g_pCError->PostHResult(hr, pIID); *ppRowsets = NULL; } }
if (DB_S_ERRORSOCCURRED == hr){ hrProp = DB_S_ERRORSOCCURRED; }
//==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProps->m_PropMemMgr.FreeDBPROPSET( cPropSets, prgPropertySets);
//=========================================================================
// We are guaranteed to have handed off the pRowsetProps value,
// so set the NULL it flag
//=========================================================================
dwFlags |= EXECUTE_NULL_PROWSETPROPS; } // Else for failure of allocation of CRowset
} else { // 07/12/2000
// Modified after finding NTBug : 142348, debugging of which
// revealed that nothing was being done if a query is to be
// executed without requiring a resultant rowset
// Just execute the query here, without worring about
// building the resulting rowset
hr = m_pCDBSession->ExecuteQuery(m_pQuery); }
if (!FAILED(hr)) { //=========================================================================
// We are guarunteed to have handed off the pRowsetProps value, so set
// the NULL it flag
//=========================================================================
dwFlags |= EXECUTE_NULL_PROWSETPROPS;
// 07/12/2000
// NTRaid : 142348
// Query for the rowset only if any rowset is asked for
if ( !(dwFlags & EXECUTE_NOROWSET) ) {
//=========================================================================
// Get the requested interface
//=========================================================================
if ( FAILED(hr = pCRowset->QueryInterface( riid, (LPVOID*) ppRowsets)) ){ // g_pCError->PostHResult(hr, pIID);
} else{ //=====================================================================
// If IID_NULL was specified, it is assumed that you
// are not getting a rowset set back, but just in case
// we'll close the statement handle
//=====================================================================
} } } // If(!Failed(hr))
} // if succeeded(hr) after BuildBindInfo()
} if (pCRowset) { pCRowset->Release(); } if (pCUtlParam) { pCUtlParam->Release(); }
hr = FAILED(hr) ? hr : hrProp;
hr = hr == S_OK ? hr :g_pCError->PostHResult(hr,pIID); return hr;
/*
EXIT_EXECUTE: //=========================================================================
// It is possible that we have gotten to this point and have handled off
// our pRowsetProps pointer to the rowset, but have no NULL'd the
// pointer. NULL it if flag is on.
//=========================================================================
if (dwFlags & EXECUTE_NULL_PROWSETPROPS) pRowsetProps = NULL;
if (pCRowset) pCRowset->Release();
if (pCUtlParam){ pCUtlParam->Release(); }
delete pRowsetProps;
return hr;*/ }
//////////////////////////////////////////////////////////////////////////////////////////////
// Function to get the DBPROP_WMIOLEDB_QUERYLANGUAGE property
// NTRaid 134165
//////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CCommand::GetQueryLanguage(VARIANT &varProp) { HRESULT hr = S_OK; ULONG cPropertySets = 0; DBPROPSET* prgPropertySets = NULL; DBPROPIDSET rgPropertyIDSets[1]; DBPROPID rgPropId[1];
VariantClear(&varProp);
//========================================================================
// Get the value of the required rowset property
//========================================================================
rgPropertyIDSets[0].guidPropertySet = DBPROPSET_WMIOLEDB_ROWSET; rgPropertyIDSets[0].rgPropertyIDs = rgPropId; rgPropertyIDSets[0].cPropertyIDs = 1; rgPropId[0] = DBPROP_WMIOLEDB_QUERYLANGUAGE;
if( S_OK == (hr = m_pUtilProps->GetProperties( PROPSET_COMMAND, 1, rgPropertyIDSets,&cPropertySets, &prgPropertySets ))) VariantCopy(&varProp,&prgPropertySets->rgProperties->vValue);
//==========================================================================
// Free memory we allocated to by GetProperties
//==========================================================================
m_pUtilProps->m_PropMemMgr.FreeDBPROPSET( cPropertySets, prgPropertySets);
return hr; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//***********************************************************************************************************
//
// Class CQuery
//
//***********************************************************************************************************
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
CQuery::CQuery() { m_prgbCallParams = NULL; m_dwStatus = 0; m_dwCancelStatus = 0; m_prgProviderParamInfo = NULL; m_pwstrWMIText = NULL; m_pwstrQryLang = NULL;
//===============================================
// Init critical section
//===============================================
m_pcsQuery = new CCriticalSection(TRUE); m_uRsType = COMMAND_ROWSET; // By default, set it for commands, can reset it to methods when needed.
m_pParamList = NULL;
} /////////////////////////////////////////////////////////////////////////////////////////////////////////////
CQuery::~CQuery() { DeleteConsumerParamInfo(); SAFE_DELETE_ARRAY( m_prgProviderParamInfo ); SAFE_DELETE_ARRAY( m_prgbCallParams ); SAFE_DELETE_PTR( m_pcsQuery ); SAFE_DELETE_ARRAY( m_pwstrWMIText ); SAFE_DELETE_ARRAY( m_pwstrQryLang );
} //////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Deletes the consumer specified parameter information.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void CQuery::DeleteConsumerParamInfo(void) { ULONG iElem;
if( m_pParamList ){ ULONG cElem = GetParamCount(); for (iElem = 0; iElem < cElem; iElem++) { PPARAMINFO pParamInfo; pParamInfo = (PPARAMINFO) m_pParamList->GetAt(iElem); delete pParamInfo; } SAFE_DELETE_PTR(m_pParamList); } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Deletes the consumer specified parameter information.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CQuery::AddConsumerParamInfo(ULONG_PTR ulParams,PPARAMINFO pParamInfo) { HRESULT hr = E_FAIL;
if( !m_pParamList ){ m_pParamList = new CFlexArray(PARAM_LIST_SIZE,50); }
if( m_pParamList ){
if( ulParams < PARAM_LIST_SIZE ){
m_pParamList->InsertAt((int)ulParams,pParamInfo); hr = S_OK; } else{
// There is a bug here with CFlexArray, when you add to it, it messes up the ordinal position
// need to work with the owners of CFlexArray to fix this
} }
return hr; }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Gets the parameter information for a specific parameter.
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
PPARAMINFO CQuery::GetParamInfo( ULONG iParams ) { PPARAMINFO pParamInfo = NULL; ULONG uSize = GetParamCount(); if( uSize > 0 ){ if ( iParams <= uSize){
pParamInfo = (PPARAMINFO)m_pParamList->GetAt(iParams); if (pParamInfo) return pParamInfo; } pParamInfo = m_prgProviderParamInfo ? m_prgProviderParamInfo + iParams : NULL; } return pParamInfo; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CQuery::InitQuery(BSTR strQryLang) { HRESULT hr = S_OK;
if( m_pwstrWMIText ){ delete []m_pwstrWMIText; } m_pwstrWMIText = NULL;
// NTRaid 135165
hr = SetQueryLanguage(strQryLang);
return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CQuery::GetQuery(WCHAR *& wcsQuery) { HRESULT hr = E_FAIL; //===============================================================================
// Initialize output parameter
//===============================================================================
wcsQuery = NULL; //===============================================================================
// Allocate memory for the string we're going to return to the caller
//===============================================================================
wcsQuery = (LPWSTR)g_pIMalloc->Alloc((wcslen(m_pwstrWMIText) + 1) * sizeof(WCHAR)); if ( !wcsQuery ){ hr = g_pCError->PostHResult((E_OUTOFMEMORY), &IID_ICommandText); hr = E_OUTOFMEMORY; } else{ wcscpy(wcsQuery, m_pwstrWMIText); }
return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CQuery::SetQuery(LPCOLESTR wcsQuery, GUID rguidDialect) { HRESULT hr = E_FAIL;
ULONG cwch = wcslen(wcsQuery); LPWSTR pwstr = new WCHAR[cwch+2]; if (pwstr){
//=================================================================
// Save the text and dialect
//=================================================================
m_cwchWMIText = cwch; m_pwstrWMIText = pwstr; wcscpy(pwstr, wcsQuery); m_guidCmdDialect = rguidDialect;
//=================================================================
// Set status flag that we have set text
//=================================================================
m_dwStatus = CMD_TEXT_SET;
//=================================================================
// Count the number of parameters
//pcmd->m_cParams = pcmd->CountParamMarkers(pwstr, cwch);
//=================================================================
hr = S_OK; } else{ hr = g_pCError->PostHResult((E_OUTOFMEMORY),&IID_ICommandText); } return hr; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CQuery::SetDefaultQuery() { m_cwchWMIText = 0; InitQuery(); m_guidCmdDialect = DBGUID_WQL; m_dwStatus &= ~CMD_TEXT_SET;
return S_OK; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT CQuery::CancelQuery() { return E_FAIL; }
DBTYPE CQuery::GetParamType(DBORDINAL lOrdinal) { PPARAMINFO param = NULL;
param = (PPARAMINFO)m_pParamList->GetAt((int)lOrdinal); assert(param); return param->wOLEDBType; }
////////////////////////////////////////////////////////////////////////
// set the query language
// NTRaid 135165
////////////////////////////////////////////////////////////////////////
HRESULT CQuery::SetQueryLanguage(BSTR strQryLang) { HRESULT hr = S_OK; if(strQryLang) { SAFE_DELETE_ARRAY( m_pwstrQryLang ); m_pwstrQryLang = new WCHAR[(SysStringLen(strQryLang) + 1) * sizeof(WCHAR)]; if(m_pwstrQryLang) { wcscpy(m_pwstrQryLang,strQryLang); } else { hr = E_OUTOFMEMORY; } } else if(m_pwstrQryLang == NULL) { m_pwstrQryLang = new WCHAR[wcslen(DEFAULTQUERYLANG) + 1]; if(m_pwstrQryLang) { wcscpy(m_pwstrQryLang,DEFAULTQUERYLANG); } else { hr = E_OUTOFMEMORY; } }
return hr; }
|