409 lines
16 KiB
C++
409 lines
16 KiB
C++
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft WMI OLE DB Provider
|
|
// (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// Command base Routines
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
#ifndef __COMMAND_H__
|
|
#define __COMMAND_H__
|
|
|
|
#include "errinf.h"
|
|
#include "utlparam.h"
|
|
#include "utilprop.h"
|
|
|
|
class CCommand;
|
|
class CImpIAccessor;
|
|
class CColInfo;
|
|
class CImpIColumnsInfoCmd;
|
|
|
|
typedef CCommand* PCCOMMAND;
|
|
typedef CImpIConvertType* PIMPICONVERTTYPE;
|
|
typedef CImpIColumnsInfoCmd* PIMPCOLINFOCMD;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// For CCommand::m_dwStatus
|
|
// These are bit masks.
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
enum COMMAND_STATUS_FLAG {
|
|
// Command Object status flags
|
|
CMD_TEXT_SET = 0x00000001, // Set when the command is set
|
|
CMD_READY = 0x00000002, //
|
|
CMD_EXECUTED_ONCE = 0x00000004, // Set when the command has changed.
|
|
CMD_TEXT_PARSED = 0X00000008, // Set if text has been parsed
|
|
CMD_PARAMS_USED = 0x00000010, // command uses parameters
|
|
CMD_HAVE_COLUMNINFO = 0x00000020,
|
|
CMD_EXEC_CANCELED = 0x00000040,
|
|
CMD_EXEC_CANCELED_BEFORE_CQUERY_SET = 0x00000080,
|
|
/* = 0x00000100,
|
|
= 0x00000200,
|
|
= 0x00000400,
|
|
= 0x00000800,
|
|
= 0x00001000,
|
|
= 0x00002000,
|
|
= 0x00004000,
|
|
= 0x00008000,
|
|
= 0x00010000,
|
|
= 0x00020000,
|
|
= 0x10000000,
|
|
= 0x20000000,*/
|
|
};
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Constant values for dwFlags on ICommand::Execute
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
const DWORD EXECUTE_NOROWSET = 0x00000001;
|
|
const DWORD EXECUTE_SUCCESSWITHINFO = 0x00000002;
|
|
const DWORD EXECUTE_NEWSTMT = 0x00000004;
|
|
const DWORD EXECUTE_NONROWRETURNING = 0x00000008;
|
|
const DWORD EXECUTE_RESTART = 0x00000010;
|
|
const DWORD EXECUTE_MULTIPLERESULTS = 0x00000020;
|
|
const DWORD EXECUTE_NULL_PROWSETPROPS = 0x00000040;
|
|
const DWORD EXECUTE_ERROR = 0x00000080;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Used in escape code processing
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
const WCHAR x_wchSTX = L'\02';
|
|
const WCHAR x_wchETX = L'\03';
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// CCommand::m_prgbCallParams constants
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
enum
|
|
{
|
|
CALL_NULL = 0,
|
|
CALL_PARAM,
|
|
CALL_RETURNSTATUS
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Defines for UnprepareHelper
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
enum
|
|
{
|
|
UNPREPARE_RESET_STMT,
|
|
UNPREPARE_RESET_CMD,
|
|
UNPREPARE_NEW_CMD
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
struct PARAMTYPE
|
|
{
|
|
PWSTR pwszName; // Type Name
|
|
WORD wWMIType; // Default WMI Server Type for above name
|
|
WORD wDBType; // Default OLE DB type for above name
|
|
LONG cbLength; // length of WMI Server Type
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
class CQuery
|
|
{
|
|
private:
|
|
|
|
DWORD m_dwStatus; // Execution Status Flags
|
|
DWORD m_dwCancelStatus; // Cancel status flags
|
|
LPWSTR m_pwstrWMIText; // current WMI text, if any
|
|
ULONG m_cwchWMIText; // length of current WMI text
|
|
GUID m_guidCmdDialect; // GUID for dialect of current text or tree
|
|
unsigned int m_uRsType;
|
|
CFlexArray * m_pParamList; // Consumer provided param info
|
|
CUtlParam* m_pCUtlParam;
|
|
LPWSTR m_pwstrQryLang;
|
|
|
|
|
|
public:
|
|
|
|
CQuery ();
|
|
~CQuery();
|
|
|
|
CCriticalSection *m_pcsQuery; //Critical Section for Query
|
|
|
|
HRESULT InitQuery(BSTR strQryLang = NULL);
|
|
HRESULT SetQuery(LPCOLESTR wcsQuery, GUID rguidDialect);
|
|
HRESULT SetDefaultQuery();
|
|
HRESULT GetQuery(WCHAR *& wcsQuery);
|
|
LPWSTR GetQuery() { return m_pwstrWMIText; }
|
|
LPWSTR GetQueryLang() { return m_pwstrQryLang; }
|
|
HRESULT CancelQuery();
|
|
HRESULT AddConsumerParamInfo(ULONG_PTR ulParams,PPARAMINFO pParamInfo);
|
|
|
|
inline DWORD GetStatus() { return m_dwStatus; }
|
|
inline DWORD GetStatus(DWORD dw) { return (m_dwStatus & dw); }
|
|
inline void SetStatus(DWORD dw) { m_dwStatus |= dw; }
|
|
inline void InitStatus(DWORD dw) { m_dwStatus = dw; }
|
|
inline void ClearStatus(DWORD dw) { m_dwStatus &= ~dw; }
|
|
|
|
inline GUID GetDialectGuid() { return m_guidCmdDialect; }
|
|
|
|
inline DWORD GetCancelStatus() { return m_dwCancelStatus;}
|
|
inline void SetCancelStatus(DWORD dw) { m_dwCancelStatus |= dw; }
|
|
inline void ClearCancelStatus(DWORD dw) { m_dwCancelStatus &= ~dw; }
|
|
|
|
inline BOOL FIsEmpty() const { return (m_cwchWMIText == 0); }
|
|
inline BYTE* RgbCallParams() const { return m_prgbCallParams;}
|
|
inline BOOL FAreParametersUsed() { return !!(m_dwStatus & CMD_PARAMS_USED); };
|
|
inline void SetProviderParamInfo(PPARAMINFO prgParamInfo){ m_prgProviderParamInfo = prgParamInfo; }
|
|
void DeleteConsumerParamInfo(void);
|
|
HRESULT SetQueryLanguage(BSTR strQryLang);
|
|
PPARAMINFO GetParamInfo(ULONG iParams);
|
|
|
|
inline void SetBindInfo(CUtlParam* pCUtlParam){
|
|
pCUtlParam->AddRef();
|
|
m_pCUtlParam = pCUtlParam;
|
|
}
|
|
|
|
PPARAMINFO m_prgProviderParamInfo;
|
|
BYTE* m_prgbCallParams; // information about param markes
|
|
// in {call..} statements
|
|
|
|
inline PPARAMINFO GetParam(ULONG u )
|
|
{
|
|
if(m_pParamList != NULL)
|
|
return (PPARAMINFO) m_pParamList->GetAt(u);
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
inline ULONG GetParamCount() const
|
|
{
|
|
if( m_pParamList )
|
|
return m_pParamList->Size();
|
|
return 0;
|
|
}
|
|
inline void RemoveParam(ULONG_PTR u)
|
|
{
|
|
if( m_pParamList )
|
|
m_pParamList->RemoveAt((int)u);
|
|
}
|
|
inline unsigned int GetType() { return m_uRsType;}
|
|
inline void SetType(unsigned int x) { m_uRsType = x; }
|
|
DBTYPE GetParamType(DBORDINAL lOrdinal);
|
|
|
|
};
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
class CImpICommandText : public ICommandText
|
|
{
|
|
private:
|
|
PCCOMMAND m_pcmd;
|
|
DEBUGCODE(ULONG m_cRef);
|
|
|
|
|
|
public:
|
|
CImpICommandText(PCCOMMAND pcmd)
|
|
{
|
|
m_pcmd = pcmd;
|
|
DEBUGCODE(m_cRef = 0);
|
|
}
|
|
|
|
~CImpICommandText() {}
|
|
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
|
|
STDMETHODIMP Cancel();
|
|
STDMETHODIMP Execute( IUnknown* pUnkOuter, REFIID riid, DBPARAMS* pParams, DBROWCOUNT* pcRowsAffected, IUnknown** ppRowset );
|
|
STDMETHODIMP GetDBSession(REFIID riid, IUnknown** ppSession);
|
|
|
|
STDMETHODIMP GetCommandText(GUID* pguidDialect, LPOLESTR* ppwszCommand);
|
|
STDMETHODIMP SetCommandText(REFGUID rguidDialect, LPCOLESTR pwszCommand);
|
|
};
|
|
typedef CImpICommandText* PIMPICOMMANDTEXT;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
class CImpICommandWithParameters : public ICommandWithParameters
|
|
{
|
|
private:
|
|
DEBUGCODE(ULONG m_cRef);
|
|
PCCOMMAND m_pcmd;
|
|
|
|
public:
|
|
CImpICommandWithParameters(PCCOMMAND pcmd){ DEBUGCODE(m_cRef = 0L); m_pcmd = pcmd; }
|
|
~CImpICommandWithParameters() {}
|
|
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
|
|
|
|
STDMETHODIMP GetParameterInfo( DB_UPARAMS* pcParams, DBPARAMINFO** prgParamInfo, OLECHAR** ppNamesBuffer );
|
|
STDMETHODIMP MapParameterNames( DB_UPARAMS cParamNames, const OLECHAR* rgParamNames[], DB_LPARAMS rgParamOrdinals[] );
|
|
STDMETHODIMP SetParameterInfo( DB_UPARAMS cParams, const DB_UPARAMS rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[] );
|
|
};
|
|
|
|
typedef CImpICommandWithParameters* PIMPICOMMANDWITHPARAMETERS;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
class CImpICommandProperties : public ICommandProperties
|
|
{
|
|
private:
|
|
DEBUGCODE(ULONG m_cRef);
|
|
PCCOMMAND m_pcmd;
|
|
|
|
public:
|
|
|
|
CImpICommandProperties(PCCOMMAND pcmd){ DEBUGCODE(m_cRef = 0L); m_pcmd = pcmd; }
|
|
~CImpICommandProperties() {}
|
|
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
|
|
|
|
STDMETHODIMP GetProperties( const ULONG cPropertySets,
|
|
const DBPROPIDSET rgPropertySets[],
|
|
ULONG* pcProperties,
|
|
DBPROPSET** prgProperties
|
|
);
|
|
STDMETHODIMP SetProperties( ULONG cProperties, DBPROPSET rgProperties[] );
|
|
};
|
|
|
|
typedef CImpICommandProperties* PIMPICOMMANDPROPERTIES;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
class CCommand : public CBaseObj
|
|
{
|
|
// Contained interfaces are friends
|
|
friend class CImpIAccessor;
|
|
friend class CImpICommandText;
|
|
friend class CImpICommandWithParameters;
|
|
friend class CImpICommandProperties;
|
|
friend class CImpIColumnsInfo;
|
|
friend class CImpIConvertType;
|
|
friend class CImpIPersistFile;
|
|
friend class CImpISupportErrorInfo;
|
|
friend class CTableDefinition;
|
|
friend class CIndexDefinition;
|
|
friend class CImpIColumnsInfoCmd;
|
|
|
|
protected:
|
|
CImpIAccessor *m_pIAccessor;
|
|
CImpICommandText *m_pICommandText;
|
|
CImpICommandWithParameters *m_pICommandWithParameters;
|
|
CImpICommandProperties *m_pICommandProperties;
|
|
CImpIColumnsInfoCmd *m_pIColumnsInfo;
|
|
CImpIConvertType *m_pIConvertType;
|
|
CImpISupportErrorInfo *m_pISupportErrorInfo;
|
|
|
|
|
|
LPBITARRAY m_pbitarrayParams; //@cmember bit array to mark referenced params
|
|
|
|
|
|
CDBSession* m_pCDBSession; //Parent Session Object
|
|
CUtilProp * m_pUtilProps; //Rowset Properties
|
|
CError m_CError; //Error data object
|
|
CQuery* m_pQuery; //Statement object
|
|
|
|
ULONG m_cRowsetsOpen; //Count of Active Rowsets on this command object
|
|
|
|
GUID m_guidImpersonate; // Impersonation GUID
|
|
// DBCOLUMNINFO m_CRowMetadata; // metadata for first statement in the command
|
|
CExtBuffer m_extNamePool; // name pool for row metadata
|
|
DWORD m_dwStatusPrep; // rowset status for prepared command
|
|
|
|
cRowColumnInfoMemMgr * m_pColumns;
|
|
DBCOUNTITEM m_cTotalCols; // Total number of columns
|
|
DBCOUNTITEM m_cCols; // Count of Parent Columns in Result Set
|
|
DBCOUNTITEM m_cNestedCols; // Number of child rowsets ( chaptered columns)
|
|
|
|
HRESULT AddInterfacesForISupportErrorInfo();
|
|
|
|
public:
|
|
CCommand(CDBSession* pCSession, LPUNKNOWN pUnkOuter);
|
|
~CCommand();
|
|
|
|
inline CImpIAccessor * GetIAccessorPtr() { return m_pIAccessor; }
|
|
HRESULT FInit(CCommand* pCloneCmd, const IID* piid);
|
|
HRESULT FInit(WORD wRowsetProps = 0);
|
|
|
|
STDMETHODIMP QueryInterface(REFIID, LPVOID *);
|
|
STDMETHODIMP_(ULONG) AddRef(void);
|
|
STDMETHODIMP_(ULONG) Release(void);
|
|
|
|
virtual HRESULT ReExecute(CRowset* pCRowset,LONG* pcCursorRows, WORD* pcCols );
|
|
|
|
inline HRESULT CheckCanceledHelper(CQuery* pstmt);
|
|
inline CDBSession* GetSessionObject() { return m_pCDBSession; };
|
|
inline CQuery* GetStmt() { return m_pQuery; }
|
|
inline CError* GetErrorData() { return &m_CError; }
|
|
// inline CUtilProps* GetRowsetProps() { return &m_CUtilProps;}
|
|
inline void DecrementOpenRowsets() { if(m_cRowsetsOpen > 0) {InterlockedDecrement( (LONG*) &m_cRowsetsOpen ); assert( m_cRowsetsOpen != ULONG(-1) );} }
|
|
inline void IncrementOpenRowsets() { InterlockedIncrement( (LONG*) &m_cRowsetsOpen ); }
|
|
inline BOOL IsRowsetOpen() { return (m_cRowsetsOpen > 0) ? TRUE : FALSE; };
|
|
|
|
|
|
HRESULT GetColumnInfo( const IID* piid, DBCOLUMNINFO *pDBCOLUMNINFO, // OUT | pointer to the row metadata
|
|
CExtBuffer **ppextBuffer // OUT | pointer to the name pool
|
|
);
|
|
void SetColumnInfo( DBCOLUMNINFO *DBCOLUMNINFO, // IN | pointer to the row metadata
|
|
CExtBuffer * pextBuffer); // IN | pointer to the name pool
|
|
|
|
STDMETHODIMP MapParameterNames( DB_UPARAMS cPNames, const OLECHAR* rgPNames[], DB_LPARAMS rgPOrdinals[], const IID* piid );
|
|
STDMETHODIMP Execute( IUnknown* pUnkOuter, REFIID riid, DBPARAMS* pParams, DBROWCOUNT* pcRowsAffected, IUnknown** ppRowsets );
|
|
STDMETHODIMP ExecuteWithParameters( DBPARAMS *pParams, DWORD *dwFlags, const IID *piid );
|
|
STDMETHODIMP OpenRowset( IUnknown* pUnkOuter, DBID* pTableID, REFIID riid, ULONG cPropertySets, DBPROPSET rgPropertySets[], IUnknown** ppRowset);
|
|
STDMETHODIMP UnprepareHelper(DWORD dwUnprepareType);
|
|
STDMETHODIMP PostExecuteErrors( CErrorData* pErrorData, const IID* piid );
|
|
STDMETHODIMP PostExecuteWarnings( CErrorData* pErrorData, const IID* piid );
|
|
STDMETHODIMP GetParamInfo( const IID *piid );
|
|
PPARAMINFO GetParamInfo( ULONG i) { return m_pQuery->GetParamInfo(i);}
|
|
|
|
HRESULT GetParameterInfo( DB_UPARAMS* pcParams, DBPARAMINFO** prgDBParamInfo, WCHAR** ppNamesBuffer, const IID* piid );
|
|
HRESULT SetParameterInfo( DB_UPARAMS cParams, const DB_UPARAMS rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[] );
|
|
|
|
BOOL FHaveBookmarks();
|
|
ULONG GetParamCount() { return m_pQuery->GetParamCount();}
|
|
DBTYPE GetParamType(DBORDINAL lOrdinal) { return m_pQuery->GetParamType(lOrdinal); }
|
|
HRESULT GetQueryLanguage(VARIANT &varProp);
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
class CImpIColumnsInfoCmd : public IColumnsInfo
|
|
{
|
|
private:
|
|
DEBUGCODE(ULONG m_cRef);
|
|
PCCOMMAND m_pcmd;
|
|
|
|
HRESULT GetColInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo,WCHAR** ppStringsBuffer);
|
|
HRESULT GatherColumnInfo();
|
|
public:
|
|
|
|
CImpIColumnsInfoCmd(PCCOMMAND pcmd)
|
|
{
|
|
DEBUGCODE(m_cRef = 0L);
|
|
m_pcmd = pcmd;
|
|
}
|
|
|
|
~CImpIColumnsInfoCmd()
|
|
{
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) AddRef(void)
|
|
{
|
|
DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
|
|
return m_pcmd->GetOuterUnknown()->AddRef();
|
|
}
|
|
|
|
STDMETHODIMP_(ULONG) Release(void)
|
|
{
|
|
DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
|
|
if( lRef < 0 ){
|
|
ASSERT("Reference count on Object went below 0!")
|
|
})
|
|
|
|
return m_pcmd->GetOuterUnknown()->Release();
|
|
|
|
}
|
|
|
|
STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
return m_pcmd->GetOuterUnknown()->QueryInterface(riid, ppv);
|
|
}
|
|
|
|
STDMETHODIMP GetColumnInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo, OLECHAR** ppStringsBuffer);
|
|
STDMETHODIMP MapColumnIDs(DBORDINAL, const DBID[], DBORDINAL[]);
|
|
};
|
|
|
|
#endif // __COMMAND_H__
|
|
|