Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
16 KiB

  1. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMI OLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // Command base Routines
  7. //
  8. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #ifndef __COMMAND_H__
  10. #define __COMMAND_H__
  11. #include "errinf.h"
  12. #include "utlparam.h"
  13. #include "utilprop.h"
  14. class CCommand;
  15. class CImpIAccessor;
  16. class CColInfo;
  17. class CImpIColumnsInfoCmd;
  18. typedef CCommand* PCCOMMAND;
  19. typedef CImpIConvertType* PIMPICONVERTTYPE;
  20. typedef CImpIColumnsInfoCmd* PIMPCOLINFOCMD;
  21. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  22. // For CCommand::m_dwStatus
  23. // These are bit masks.
  24. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  25. enum COMMAND_STATUS_FLAG {
  26. // Command Object status flags
  27. CMD_TEXT_SET = 0x00000001, // Set when the command is set
  28. CMD_READY = 0x00000002, //
  29. CMD_EXECUTED_ONCE = 0x00000004, // Set when the command has changed.
  30. CMD_TEXT_PARSED = 0X00000008, // Set if text has been parsed
  31. CMD_PARAMS_USED = 0x00000010, // command uses parameters
  32. CMD_HAVE_COLUMNINFO = 0x00000020,
  33. CMD_EXEC_CANCELED = 0x00000040,
  34. CMD_EXEC_CANCELED_BEFORE_CQUERY_SET = 0x00000080,
  35. /* = 0x00000100,
  36. = 0x00000200,
  37. = 0x00000400,
  38. = 0x00000800,
  39. = 0x00001000,
  40. = 0x00002000,
  41. = 0x00004000,
  42. = 0x00008000,
  43. = 0x00010000,
  44. = 0x00020000,
  45. = 0x10000000,
  46. = 0x20000000,*/
  47. };
  48. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  49. // Constant values for dwFlags on ICommand::Execute
  50. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  51. const DWORD EXECUTE_NOROWSET = 0x00000001;
  52. const DWORD EXECUTE_SUCCESSWITHINFO = 0x00000002;
  53. const DWORD EXECUTE_NEWSTMT = 0x00000004;
  54. const DWORD EXECUTE_NONROWRETURNING = 0x00000008;
  55. const DWORD EXECUTE_RESTART = 0x00000010;
  56. const DWORD EXECUTE_MULTIPLERESULTS = 0x00000020;
  57. const DWORD EXECUTE_NULL_PROWSETPROPS = 0x00000040;
  58. const DWORD EXECUTE_ERROR = 0x00000080;
  59. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  60. // Used in escape code processing
  61. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  62. const WCHAR x_wchSTX = L'\02';
  63. const WCHAR x_wchETX = L'\03';
  64. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. // CCommand::m_prgbCallParams constants
  66. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  67. enum
  68. {
  69. CALL_NULL = 0,
  70. CALL_PARAM,
  71. CALL_RETURNSTATUS
  72. };
  73. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  74. // Defines for UnprepareHelper
  75. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  76. enum
  77. {
  78. UNPREPARE_RESET_STMT,
  79. UNPREPARE_RESET_CMD,
  80. UNPREPARE_NEW_CMD
  81. };
  82. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. struct PARAMTYPE
  84. {
  85. PWSTR pwszName; // Type Name
  86. WORD wWMIType; // Default WMI Server Type for above name
  87. WORD wDBType; // Default OLE DB type for above name
  88. LONG cbLength; // length of WMI Server Type
  89. };
  90. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  91. class CQuery
  92. {
  93. private:
  94. DWORD m_dwStatus; // Execution Status Flags
  95. DWORD m_dwCancelStatus; // Cancel status flags
  96. LPWSTR m_pwstrWMIText; // current WMI text, if any
  97. ULONG m_cwchWMIText; // length of current WMI text
  98. GUID m_guidCmdDialect; // GUID for dialect of current text or tree
  99. unsigned int m_uRsType;
  100. CFlexArray * m_pParamList; // Consumer provided param info
  101. CUtlParam* m_pCUtlParam;
  102. LPWSTR m_pwstrQryLang;
  103. public:
  104. CQuery ();
  105. ~CQuery();
  106. CCriticalSection *m_pcsQuery; //Critical Section for Query
  107. HRESULT InitQuery(BSTR strQryLang = NULL);
  108. HRESULT SetQuery(LPCOLESTR wcsQuery, GUID rguidDialect);
  109. HRESULT SetDefaultQuery();
  110. HRESULT GetQuery(WCHAR *& wcsQuery);
  111. LPWSTR GetQuery() { return m_pwstrWMIText; }
  112. LPWSTR GetQueryLang() { return m_pwstrQryLang; }
  113. HRESULT CancelQuery();
  114. HRESULT AddConsumerParamInfo(ULONG_PTR ulParams,PPARAMINFO pParamInfo);
  115. inline DWORD GetStatus() { return m_dwStatus; }
  116. inline DWORD GetStatus(DWORD dw) { return (m_dwStatus & dw); }
  117. inline void SetStatus(DWORD dw) { m_dwStatus |= dw; }
  118. inline void InitStatus(DWORD dw) { m_dwStatus = dw; }
  119. inline void ClearStatus(DWORD dw) { m_dwStatus &= ~dw; }
  120. inline GUID GetDialectGuid() { return m_guidCmdDialect; }
  121. inline DWORD GetCancelStatus() { return m_dwCancelStatus;}
  122. inline void SetCancelStatus(DWORD dw) { m_dwCancelStatus |= dw; }
  123. inline void ClearCancelStatus(DWORD dw) { m_dwCancelStatus &= ~dw; }
  124. inline BOOL FIsEmpty() const { return (m_cwchWMIText == 0); }
  125. inline BYTE* RgbCallParams() const { return m_prgbCallParams;}
  126. inline BOOL FAreParametersUsed() { return !!(m_dwStatus & CMD_PARAMS_USED); };
  127. inline void SetProviderParamInfo(PPARAMINFO prgParamInfo){ m_prgProviderParamInfo = prgParamInfo; }
  128. void DeleteConsumerParamInfo(void);
  129. HRESULT SetQueryLanguage(BSTR strQryLang);
  130. PPARAMINFO GetParamInfo(ULONG iParams);
  131. inline void SetBindInfo(CUtlParam* pCUtlParam){
  132. pCUtlParam->AddRef();
  133. m_pCUtlParam = pCUtlParam;
  134. }
  135. PPARAMINFO m_prgProviderParamInfo;
  136. BYTE* m_prgbCallParams; // information about param markes
  137. // in {call..} statements
  138. inline PPARAMINFO GetParam(ULONG u )
  139. {
  140. if(m_pParamList != NULL)
  141. return (PPARAMINFO) m_pParamList->GetAt(u);
  142. else
  143. return NULL;
  144. }
  145. inline ULONG GetParamCount() const
  146. {
  147. if( m_pParamList )
  148. return m_pParamList->Size();
  149. return 0;
  150. }
  151. inline void RemoveParam(ULONG_PTR u)
  152. {
  153. if( m_pParamList )
  154. m_pParamList->RemoveAt((int)u);
  155. }
  156. inline unsigned int GetType() { return m_uRsType;}
  157. inline void SetType(unsigned int x) { m_uRsType = x; }
  158. DBTYPE GetParamType(DBORDINAL lOrdinal);
  159. };
  160. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  161. class CImpICommandText : public ICommandText
  162. {
  163. private:
  164. PCCOMMAND m_pcmd;
  165. DEBUGCODE(ULONG m_cRef);
  166. public:
  167. CImpICommandText(PCCOMMAND pcmd)
  168. {
  169. m_pcmd = pcmd;
  170. DEBUGCODE(m_cRef = 0);
  171. }
  172. ~CImpICommandText() {}
  173. STDMETHODIMP_(ULONG) AddRef(void);
  174. STDMETHODIMP_(ULONG) Release(void);
  175. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  176. STDMETHODIMP Cancel();
  177. STDMETHODIMP Execute( IUnknown* pUnkOuter, REFIID riid, DBPARAMS* pParams, DBROWCOUNT* pcRowsAffected, IUnknown** ppRowset );
  178. STDMETHODIMP GetDBSession(REFIID riid, IUnknown** ppSession);
  179. STDMETHODIMP GetCommandText(GUID* pguidDialect, LPOLESTR* ppwszCommand);
  180. STDMETHODIMP SetCommandText(REFGUID rguidDialect, LPCOLESTR pwszCommand);
  181. };
  182. typedef CImpICommandText* PIMPICOMMANDTEXT;
  183. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  184. class CImpICommandWithParameters : public ICommandWithParameters
  185. {
  186. private:
  187. DEBUGCODE(ULONG m_cRef);
  188. PCCOMMAND m_pcmd;
  189. public:
  190. CImpICommandWithParameters(PCCOMMAND pcmd){ DEBUGCODE(m_cRef = 0L); m_pcmd = pcmd; }
  191. ~CImpICommandWithParameters() {}
  192. STDMETHODIMP_(ULONG) AddRef(void);
  193. STDMETHODIMP_(ULONG) Release(void);
  194. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  195. STDMETHODIMP GetParameterInfo( DB_UPARAMS* pcParams, DBPARAMINFO** prgParamInfo, OLECHAR** ppNamesBuffer );
  196. STDMETHODIMP MapParameterNames( DB_UPARAMS cParamNames, const OLECHAR* rgParamNames[], DB_LPARAMS rgParamOrdinals[] );
  197. STDMETHODIMP SetParameterInfo( DB_UPARAMS cParams, const DB_UPARAMS rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[] );
  198. };
  199. typedef CImpICommandWithParameters* PIMPICOMMANDWITHPARAMETERS;
  200. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  201. class CImpICommandProperties : public ICommandProperties
  202. {
  203. private:
  204. DEBUGCODE(ULONG m_cRef);
  205. PCCOMMAND m_pcmd;
  206. public:
  207. CImpICommandProperties(PCCOMMAND pcmd){ DEBUGCODE(m_cRef = 0L); m_pcmd = pcmd; }
  208. ~CImpICommandProperties() {}
  209. STDMETHODIMP_(ULONG) AddRef(void);
  210. STDMETHODIMP_(ULONG) Release(void);
  211. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  212. STDMETHODIMP GetProperties( const ULONG cPropertySets,
  213. const DBPROPIDSET rgPropertySets[],
  214. ULONG* pcProperties,
  215. DBPROPSET** prgProperties
  216. );
  217. STDMETHODIMP SetProperties( ULONG cProperties, DBPROPSET rgProperties[] );
  218. };
  219. typedef CImpICommandProperties* PIMPICOMMANDPROPERTIES;
  220. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  221. class CCommand : public CBaseObj
  222. {
  223. // Contained interfaces are friends
  224. friend class CImpIAccessor;
  225. friend class CImpICommandText;
  226. friend class CImpICommandWithParameters;
  227. friend class CImpICommandProperties;
  228. friend class CImpIColumnsInfo;
  229. friend class CImpIConvertType;
  230. friend class CImpIPersistFile;
  231. friend class CImpISupportErrorInfo;
  232. friend class CTableDefinition;
  233. friend class CIndexDefinition;
  234. friend class CImpIColumnsInfoCmd;
  235. protected:
  236. CImpIAccessor *m_pIAccessor;
  237. CImpICommandText *m_pICommandText;
  238. CImpICommandWithParameters *m_pICommandWithParameters;
  239. CImpICommandProperties *m_pICommandProperties;
  240. CImpIColumnsInfoCmd *m_pIColumnsInfo;
  241. CImpIConvertType *m_pIConvertType;
  242. CImpISupportErrorInfo *m_pISupportErrorInfo;
  243. LPBITARRAY m_pbitarrayParams; //@cmember bit array to mark referenced params
  244. CDBSession* m_pCDBSession; //Parent Session Object
  245. CUtilProp * m_pUtilProps; //Rowset Properties
  246. CError m_CError; //Error data object
  247. CQuery* m_pQuery; //Statement object
  248. ULONG m_cRowsetsOpen; //Count of Active Rowsets on this command object
  249. GUID m_guidImpersonate; // Impersonation GUID
  250. // DBCOLUMNINFO m_CRowMetadata; // metadata for first statement in the command
  251. CExtBuffer m_extNamePool; // name pool for row metadata
  252. DWORD m_dwStatusPrep; // rowset status for prepared command
  253. cRowColumnInfoMemMgr * m_pColumns;
  254. DBCOUNTITEM m_cTotalCols; // Total number of columns
  255. DBCOUNTITEM m_cCols; // Count of Parent Columns in Result Set
  256. DBCOUNTITEM m_cNestedCols; // Number of child rowsets ( chaptered columns)
  257. HRESULT AddInterfacesForISupportErrorInfo();
  258. public:
  259. CCommand(CDBSession* pCSession, LPUNKNOWN pUnkOuter);
  260. ~CCommand();
  261. inline CImpIAccessor * GetIAccessorPtr() { return m_pIAccessor; }
  262. HRESULT FInit(CCommand* pCloneCmd, const IID* piid);
  263. HRESULT FInit(WORD wRowsetProps = 0);
  264. STDMETHODIMP QueryInterface(REFIID, LPVOID *);
  265. STDMETHODIMP_(ULONG) AddRef(void);
  266. STDMETHODIMP_(ULONG) Release(void);
  267. virtual HRESULT ReExecute(CRowset* pCRowset,LONG* pcCursorRows, WORD* pcCols );
  268. inline HRESULT CheckCanceledHelper(CQuery* pstmt);
  269. inline CDBSession* GetSessionObject() { return m_pCDBSession; };
  270. inline CQuery* GetStmt() { return m_pQuery; }
  271. inline CError* GetErrorData() { return &m_CError; }
  272. // inline CUtilProps* GetRowsetProps() { return &m_CUtilProps;}
  273. inline void DecrementOpenRowsets() { if(m_cRowsetsOpen > 0) {InterlockedDecrement( (LONG*) &m_cRowsetsOpen ); assert( m_cRowsetsOpen != ULONG(-1) );} }
  274. inline void IncrementOpenRowsets() { InterlockedIncrement( (LONG*) &m_cRowsetsOpen ); }
  275. inline BOOL IsRowsetOpen() { return (m_cRowsetsOpen > 0) ? TRUE : FALSE; };
  276. HRESULT GetColumnInfo( const IID* piid, DBCOLUMNINFO *pDBCOLUMNINFO, // OUT | pointer to the row metadata
  277. CExtBuffer **ppextBuffer // OUT | pointer to the name pool
  278. );
  279. void SetColumnInfo( DBCOLUMNINFO *DBCOLUMNINFO, // IN | pointer to the row metadata
  280. CExtBuffer * pextBuffer); // IN | pointer to the name pool
  281. STDMETHODIMP MapParameterNames( DB_UPARAMS cPNames, const OLECHAR* rgPNames[], DB_LPARAMS rgPOrdinals[], const IID* piid );
  282. STDMETHODIMP Execute( IUnknown* pUnkOuter, REFIID riid, DBPARAMS* pParams, DBROWCOUNT* pcRowsAffected, IUnknown** ppRowsets );
  283. STDMETHODIMP ExecuteWithParameters( DBPARAMS *pParams, DWORD *dwFlags, const IID *piid );
  284. STDMETHODIMP OpenRowset( IUnknown* pUnkOuter, DBID* pTableID, REFIID riid, ULONG cPropertySets, DBPROPSET rgPropertySets[], IUnknown** ppRowset);
  285. STDMETHODIMP UnprepareHelper(DWORD dwUnprepareType);
  286. STDMETHODIMP PostExecuteErrors( CErrorData* pErrorData, const IID* piid );
  287. STDMETHODIMP PostExecuteWarnings( CErrorData* pErrorData, const IID* piid );
  288. STDMETHODIMP GetParamInfo( const IID *piid );
  289. PPARAMINFO GetParamInfo( ULONG i) { return m_pQuery->GetParamInfo(i);}
  290. HRESULT GetParameterInfo( DB_UPARAMS* pcParams, DBPARAMINFO** prgDBParamInfo, WCHAR** ppNamesBuffer, const IID* piid );
  291. HRESULT SetParameterInfo( DB_UPARAMS cParams, const DB_UPARAMS rgParamOrdinals[], const DBPARAMBINDINFO rgParamBindInfo[] );
  292. BOOL FHaveBookmarks();
  293. ULONG GetParamCount() { return m_pQuery->GetParamCount();}
  294. DBTYPE GetParamType(DBORDINAL lOrdinal) { return m_pQuery->GetParamType(lOrdinal); }
  295. HRESULT GetQueryLanguage(VARIANT &varProp);
  296. };
  297. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  298. class CImpIColumnsInfoCmd : public IColumnsInfo
  299. {
  300. private:
  301. DEBUGCODE(ULONG m_cRef);
  302. PCCOMMAND m_pcmd;
  303. HRESULT GetColInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo,WCHAR** ppStringsBuffer);
  304. HRESULT GatherColumnInfo();
  305. public:
  306. CImpIColumnsInfoCmd(PCCOMMAND pcmd)
  307. {
  308. DEBUGCODE(m_cRef = 0L);
  309. m_pcmd = pcmd;
  310. }
  311. ~CImpIColumnsInfoCmd()
  312. {
  313. }
  314. STDMETHODIMP_(ULONG) AddRef(void)
  315. {
  316. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  317. return m_pcmd->GetOuterUnknown()->AddRef();
  318. }
  319. STDMETHODIMP_(ULONG) Release(void)
  320. {
  321. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  322. if( lRef < 0 ){
  323. ASSERT("Reference count on Object went below 0!")
  324. })
  325. return m_pcmd->GetOuterUnknown()->Release();
  326. }
  327. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  328. {
  329. return m_pcmd->GetOuterUnknown()->QueryInterface(riid, ppv);
  330. }
  331. STDMETHODIMP GetColumnInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo, OLECHAR** ppStringsBuffer);
  332. STDMETHODIMP MapColumnIDs(DBORDINAL, const DBID[], DBORDINAL[]);
  333. };
  334. #endif // __COMMAND_H__