windows-nt/Source/XPSP1/NT/admin/wmi/wbem/adapters/oledb/command.cpp
2020-09-26 16:20:57 +08:00

1072 lines
36 KiB
C++

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