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.

975 lines
32 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft WMIOLE DB Provider
  4. // (C) Copyright 1999 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // @module ROWSET.H | CRowset base object and contained interface
  7. //
  8. //
  9. ///////////////////////////////////////////////////////////////////////////////////
  10. #ifndef _ROWSET_H_
  11. #define _ROWSET_H_
  12. #include "baserowobj.h"
  13. #include "bitarray.h"
  14. /////////////////////////////////////////////////////////////////////////////////////////////////////
  15. #define COLUMNINFO_SIZE MAX_PATH*3
  16. #define DEFAULT_COLUMNS_TO_ADD 100
  17. /////////////////////////////////////////////////////////////////////////////////////////////////////
  18. #define COLUMNSTAT_MODIFIED 0x1000
  19. #define NOCOLSCHANGED 0x0010
  20. class CImpIAccessor;
  21. class CImpIGetRow;
  22. class CImplIRowsetRefresh;
  23. class CImplIParentRowset;
  24. class CQuery;
  25. class CCommand;
  26. typedef CImpIGetRow * PIMPIGETROW;
  27. typedef CImplIRowsetRefresh * PIMPIROWSETREFRESH;
  28. typedef CHashTbl * PHASHTBL;
  29. typedef CCommand * PCCOMMAND;
  30. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  31. class CRowset : public CBaseRowObj
  32. {
  33. // Contained interfaces are friends
  34. friend class CImpIRowsetLocate;
  35. friend class CImpIRowsetChange;
  36. friend class CImpIRowsetIdentity;
  37. friend class CImpIRowsetInfo;
  38. friend class CImpIAccessor;
  39. friend class CImpIGetRow;
  40. friend class CImplIRowsetRefresh;
  41. friend class CImpIChapteredRowset;
  42. friend class CRowFetchObj;
  43. friend class CInstanceRowFetchObj;
  44. friend class CQualifierRowFetchObj;
  45. friend class CRow;
  46. private:
  47. CWMIInstanceMgr * m_InstMgr; // to manage pointer to instance to HROW
  48. PIMPIROWSET m_pIRowset; // Contained IRowset
  49. PIMPIROWSETLOCATE m_pIRowsetLocate; // Contained IRowsetLocate
  50. PIMPIROWSETCHANGE m_pIRowsetChange; // Contained IRowsetChange
  51. PIMPIROWSETIDENTITY m_pIRowsetIdentity; // Contained IRowsetIdentity
  52. PIMPIACCESSOR m_pIAccessor; // Contained IAccessor
  53. PICHAPTEREDROWSET m_pIChapteredRowset; // Contained IChapteredRowset
  54. PIMPIROWSETINFO m_pIRowsetInfo; // Contained IRowsetInfo;
  55. PIMPIGETROW m_pIGetRow; // contained IGetRow
  56. PIMPIROWSETREFRESH m_pIRowsetRefresh; // Contained IRowsetIdentity
  57. PROWFETCHOBJ m_pRowFetchObj; // Rowfetch Object to fetch rows
  58. PHASHTBL m_pHashTblBkmark; // HashTable pointer to store bookmarks
  59. PCCOMMAND m_pParentCmd; // Command object which created the rowset
  60. DBORDINAL m_irowMin; // index of the first available rowbuffer
  61. ULONG_PTR m_cRows; // current # of rows in the buffer
  62. DBSTATUS m_dwStatus; // status word for the entire cursor
  63. BYTE* m_pLastBindBase; // remember last binding location
  64. DBROWCOUNT m_ulRowRefCount; // RefCount of all outstanding row handles
  65. // HCHAPTER m_hLastChapterAllocated; // variable to store the last HCHAPTER given;
  66. HCHAPTER m_hLastChapterAllocated; // variable to store the last HCHAPTER given;
  67. BOOL m_bHelperFunctionCreated; // flag to indicate whethe helper function are created or not
  68. HROW m_ulLastFetchedRow; // Position of the last fetched Row
  69. // retrieved from WMIOLEDBMAP class or not
  70. HROW m_hRowLastFetched; // last fetched HROW
  71. CBaseRowObj ** m_ppChildRowsets; // Array of rowset pointers for child recordsets
  72. BSTR m_strPropertyName; // Name of the property for which Qualifier is
  73. // is to be retrieved
  74. CWbemClassWrapper * m_pInstance; // Instance pointer of instance for which this qualifier
  75. // rowset is pointing
  76. BOOL m_bIsChildRs; // flag indicating whether the rowset is a child rowset
  77. FETCHDIRECTION m_FetchDir; // The last fetch Direction;
  78. ULONG_PTR m_lLastFetchPos; // The last fetched position
  79. DBCOUNTITEM m_lRowCount; // The number of rows in rowset
  80. HRESULT GatherColumnInfo(void); //Builds DBCOLINFO structures
  81. HRESULT ReleaseAllRows(); // release all rows during desctuction
  82. HRESULT CreateHelperFunctions(void); //Creates Helper Classes
  83. ROWBUFF* GetRowBuff(HROW iRow, BOOL fDataLocation = FALSE); //Returns the Buffer Pointer for the specified row identified from HROW
  84. ROWBUFF* GetRowBuffFromSlot(HSLOT hSlot, BOOL fDataLocation = FALSE); //Returns the Buffer Pointer for the specified row identified by slot
  85. HRESULT Rebind(BYTE* pBase); //Establishes the data area bindings
  86. HRESULT ReleaseRowData(HROW hRow,BOOL bReleaseSlot = TRUE);
  87. HRESULT ResetInstances(); // Set instance back to 0
  88. HRESULT ResetQualifers(HCHAPTER hChapter);
  89. HRESULT ResetRowsetToNewPosition(DBROWOFFSET lRowOffset,CWbemClassWrapper *pInst = NULL); // Start getting at new position
  90. HRESULT AllocateAndInitializeChildRowsets(); // ALlocate and initialize rowsets for child recordsets
  91. HRESULT GetChildRowset(DBORDINAL ulOrdinal,REFIID riid ,IUnknown ** ppIRowset); // get the pointer to the child recordsets
  92. HRESULT CheckAndInitializeChapter(HCHAPTER hChapter);
  93. HRESULT GetNextInstance(CWbemClassWrapper *&ppInst, CBSTR &strKey,BOOL bFetchBack); // Get the next one in the list
  94. HRESULT GetNextPropertyQualifier(CWbemClassWrapper *pInst,BSTR strPropName,BSTR &strQualifier,BOOL bFetchBack);
  95. HRESULT GetInstanceDataToLocalBuffer(CWbemClassWrapper *pInst,HSLOT hSlot,BSTR strQualifer = Wmioledb_SysAllocString(NULL)); // Get the Instance Data and put it into the
  96. // provider's own memory
  97. HRESULT GetNextClassQualifier(CWbemClassWrapper *pInst,BSTR &strQualifier,BOOL bFetchBack);
  98. HRESULT ReleaseInstancePointer(HROW hRow); // function to relese HROW from the chapter manager
  99. // and instance manager when row is released
  100. BOOL IsRowExists(HROW hRow);
  101. HRESULT IsSlotSet(HSLOT hRow);
  102. HSLOT GetSlotForRow(HROW hRow);
  103. HRESULT SetRowsetProperties(const ULONG cPropertySets, const DBPROPSET rgPropertySets[] );
  104. HRESULT GetData(HROW hRow ,BSTR strQualifer = Wmioledb_SysAllocString(NULL));
  105. HRESULT UpdateRowData(HROW hRow,PACCESSOR pAccessor, BOOL bNewInst);
  106. HRESULT DeleteRow(HROW hRow,DBROWSTATUS * pRowStatus);
  107. void SetRowStatus(HROW hRow , DBSTATUS dwStatus);
  108. DBSTATUS GetRowStatus(HROW hRow);
  109. void GetInstanceKey(HROW hRow , BSTR *strKey);
  110. HRESULT UpdateRowData(HROW hRow,DBORDINAL cColumns,DBCOLUMNACCESS rgColumns[ ]);
  111. void SetStatus(HCHAPTER hChapter , DWORD dwStatus);
  112. DBSTATUS GetStatus(HCHAPTER hChapter = 0);
  113. HRESULT InsertNewRow(CWbemClassWrapper **ppNewInst);
  114. HRESULT GetColumnInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo,WCHAR** ppStringsBuffer);
  115. void GetBookMark(HROW hRow,BSTR &strBookMark);
  116. HRESULT FillHChaptersForRow(CWbemClassWrapper *pInst, BSTR strKey);
  117. // HCHAPTER GetNextHChapter() { return ++m_hLastChapterAllocated; }
  118. HCHAPTER GetNextHChapter() { return ++m_hLastChapterAllocated; }
  119. HRESULT AddRefChapter(HCHAPTER hChapter,DBREFCOUNT * pcRefCount);
  120. HRESULT ReleaseRefChapter(HCHAPTER hChapter,DBREFCOUNT * pcRefCount); // Release reference to chapter
  121. HRESULT GetRowCount();
  122. HRESULT GetDataToLocalBuffer(HROW hRow);
  123. BOOL IsInstanceDeleted(CWbemClassWrapper *pInst);
  124. HRESULT AllocateInterfacePointers();
  125. void InitializeRowsetProperties();
  126. HRESULT AddInterfacesForISupportErrorInfo();
  127. CWbemClassWrapper * GetInstancePtr(HROW hRow);
  128. INSTANCELISTTYPE GetObjListType() { return m_pMap->GetObjListType(); }
  129. FETCHDIRECTION GetCurFetchDirection() { return m_pMap->GetCurFetchDirection(); }
  130. void SetCurFetchDirection(FETCHDIRECTION FetchDir);
  131. public:
  132. // For Hierarchical recordset to represent Qualifiers
  133. CRowset(LPUNKNOWN pUnkOuter,ULONG uQType, LPWSTR PropertyName,PCDBSESSION pObj , CWmiOleDBMap *pMap);
  134. CRowset(LPUNKNOWN pUnkOuter,PCDBSESSION pObj ,CWbemConnectionWrapper *pCon = NULL);
  135. ~CRowset(void);
  136. void InitVars();
  137. inline BOOL BitArrayInitialized();
  138. inline LPEXTBUFFER GetAccessorBuffer();
  139. inline PCUTILPROP GetCUtilProp() { return m_pUtilProp; }; // Return the CUtilProp object
  140. CWmiOleDBMap *GetWmiOleDBMap() { return m_pMap; };
  141. // Initialization functions
  142. HRESULT InitRowset( const ULONG cPropertySets,
  143. const DBPROPSET rgPropertySets[] );
  144. // overloaded function for rowsets resulted from executing
  145. // query from command object
  146. HRESULT InitRowset( const ULONG cPropertySets,
  147. const DBPROPSET rgPropertySets[],
  148. DWORD dwFlags,
  149. CQuery* p,
  150. PCCOMMAND pCmd );
  151. // Overloaded function for normal rowset and schema rowsets
  152. HRESULT InitRowset( int nBaseType,const ULONG cPropertySets, const DBPROPSET rgPropertySets[],LPWSTR TableID, DWORD dwFlags, LPWSTR SpecificTable );
  153. HRESULT InitRowset( const ULONG cPropertySets,
  154. const DBPROPSET rgPropertySets[],
  155. LPWSTR TableID,
  156. BOOL fSchema = FALSE,
  157. DWORD dwFlags = -1 );
  158. HRESULT InitRowset( const ULONG cPropertySets,
  159. const DBPROPSET rgPropertySets[],
  160. LPWSTR strObjectID,
  161. LPWSTR strObjectToOpen,
  162. INSTANCELISTTYPE objInstListType ,
  163. DWORD dwFlags = -1);
  164. HRESULT InitRowsetForRow( LPUNKNOWN pUnkOuter ,
  165. const ULONG cPropertySets,
  166. const DBPROPSET rgPropertySets[] ,
  167. CWbemClassWrapper *pInst);
  168. void GetQualiferName(HROW hRow,BSTR &strBookMark);
  169. // IUnknown methods
  170. STDMETHODIMP QueryInterface(REFIID, LPVOID *);
  171. STDMETHODIMP_(ULONG) AddRef(void);
  172. STDMETHODIMP_(ULONG) Release(void);
  173. };
  174. typedef CRowset *PCROWSET;
  175. ////////////////////////////////////////////////////////////////////////////////////////////////////////
  176. class CImpIRowsetLocate : public IRowsetLocate
  177. {
  178. private:
  179. DEBUGCODE(ULONG m_cRef);
  180. CRowset * m_pObj;
  181. public:
  182. CImpIRowsetLocate( CRowset *pObj )
  183. {
  184. DEBUGCODE(m_cRef = 0L);
  185. m_pObj = pObj;
  186. }
  187. ~CImpIRowsetLocate()
  188. {
  189. }
  190. STDMETHODIMP_(ULONG) AddRef(void)
  191. {
  192. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  193. return m_pObj->GetOuterUnknown()->AddRef();
  194. }
  195. STDMETHODIMP_(ULONG) Release(void)
  196. {
  197. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  198. if( lRef < 0 ){
  199. ASSERT("Reference count on Object went below 0!")
  200. })
  201. return m_pObj->GetOuterUnknown()->Release();
  202. }
  203. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  204. {
  205. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  206. }
  207. STDMETHODIMP GetData(HROW, HACCESSOR, void*);
  208. STDMETHODIMP GetNextRows(HCHAPTER, DBROWOFFSET, DBROWCOUNT, DBCOUNTITEM*, HROW**);
  209. STDMETHODIMP ReleaseRows(DBCOUNTITEM, const HROW[], DBROWOPTIONS[], DBREFCOUNT[], DBROWSTATUS[]);
  210. STDMETHODIMP RestartPosition(HCHAPTER);
  211. STDMETHODIMP AddRefRows(DBCOUNTITEM, const HROW[], DBREFCOUNT[], DBROWSTATUS[]);
  212. // IRowsetLocate Methods
  213. STDMETHODIMP Compare (HCHAPTER hChapter,
  214. DBBKMARK cbBookmark1,
  215. const BYTE * pBookmark1,
  216. DBBKMARK cbBookmark2,
  217. const BYTE * pBookmark2,
  218. DBCOMPARE * pComparison);
  219. STDMETHODIMP GetRowsAt (HWATCHREGION hReserved1,
  220. HCHAPTER hChapter,
  221. DBBKMARK cbBookmark,
  222. const BYTE * pBookmark,
  223. DBROWOFFSET lRowsOffset,
  224. DBROWCOUNT cRows,
  225. DBCOUNTITEM * pcRowsObtained,
  226. HROW ** prghRows);
  227. STDMETHODIMP GetRowsByBookmark (HCHAPTER hChapter,
  228. DBCOUNTITEM cRows,
  229. const DBBKMARK rgcbBookmarks[],
  230. const BYTE * rgpBookmarks[],
  231. HROW rghRows[],
  232. DBROWSTATUS rgRowStatus[]);
  233. STDMETHODIMP Hash (HCHAPTER hChapter,
  234. DBBKMARK cBookmarks,
  235. const DBBKMARK rgcbBookmarks[],
  236. const BYTE * rgpBookmarks[],
  237. DBHASHVALUE rgHashedValues[],
  238. DBROWSTATUS rgBookmarkStatus[]);
  239. // a utility function
  240. HRESULT CheckParameters(DBCOUNTITEM * pcRowsObtained, DBROWOFFSET lRowOffset, DBROWCOUNT cRows,HROW **prghRows );
  241. };
  242. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  243. class CImpIRowsetChange : public IRowsetChange
  244. {
  245. private:
  246. DEBUGCODE(ULONG m_cRef);
  247. CRowset *m_pObj;
  248. public:
  249. CImpIRowsetChange( CRowset *pObj )
  250. {
  251. DEBUGCODE(m_cRef = 0L);
  252. m_pObj = pObj;
  253. }
  254. ~CImpIRowsetChange()
  255. {
  256. }
  257. STDMETHODIMP_(ULONG) AddRef(void)
  258. {
  259. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  260. return m_pObj->GetOuterUnknown()->AddRef();
  261. }
  262. STDMETHODIMP_(ULONG) Release(void)
  263. {
  264. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  265. if( lRef < 0 ){
  266. ASSERT("Reference count on Object went below 0!")
  267. })
  268. return m_pObj->GetOuterUnknown()->Release();
  269. }
  270. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  271. {
  272. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  273. }
  274. STDMETHODIMP SetData(HROW, HACCESSOR, void*);
  275. STDMETHODIMP DeleteRows(HCHAPTER, DBCOUNTITEM, const HROW[], DBROWSTATUS[]);
  276. STDMETHODIMP InsertRow(HCHAPTER hChapter,HACCESSOR hAccessor, void* pData, HROW* phRow);
  277. private:
  278. STDMETHODIMP ApplyAccessorToData( DBCOUNTITEM cBindings, DBBINDING* pBinding,BYTE* pbProvRow,void* pData,DWORD & dwErrorCount );
  279. STDMETHODIMP ValidateArguments( HROW hRow,
  280. HACCESSOR hAccessor,
  281. const void *pData,
  282. PROWBUFF *pprowbuff = NULL,
  283. PACCESSOR *ppkgaccessor = NULL);
  284. BOOL CompareData(DBTYPE dwType,void * pData1 , void *pData2);
  285. HRESULT UpdateDataToRowBuffer(DBCOUNTITEM iBind ,BYTE * pbProvRow,DBBINDING* pBinding,BYTE *pData);
  286. BOOL IsNullAccessor(PACCESSOR phAccessor,BYTE * pData );
  287. HRESULT InsertNewRow(HROW hRow, HCHAPTER hChapter,CWbemClassWrapper *& pNewInst);
  288. };
  289. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  290. class CImpIColumnsInfo : public IColumnsInfo
  291. {
  292. private:
  293. DEBUGCODE(ULONG m_cRef);
  294. CBaseRowObj *m_pObj;
  295. public:
  296. CImpIColumnsInfo(CBaseRowObj *pObj)
  297. {
  298. DEBUGCODE(m_cRef = 0L);
  299. m_pObj = pObj;
  300. }
  301. ~CImpIColumnsInfo()
  302. {
  303. }
  304. STDMETHODIMP_(ULONG) AddRef(void)
  305. {
  306. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  307. return m_pObj->GetOuterUnknown()->AddRef();
  308. }
  309. STDMETHODIMP_(ULONG) Release(void)
  310. {
  311. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  312. if( lRef < 0 ){
  313. ASSERT("Reference count on Object went below 0!")
  314. })
  315. return m_pObj->GetOuterUnknown()->Release();
  316. }
  317. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  318. {
  319. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  320. }
  321. STDMETHODIMP GetColumnInfo(DBORDINAL* pcColumns, DBCOLUMNINFO** prgInfo, OLECHAR** ppStringsBuffer);
  322. STDMETHODIMP MapColumnIDs(DBORDINAL, const DBID[], DBORDINAL[]);
  323. };
  324. ////////////////////////////////////////////////////////////////////////////////////////////////////////////
  325. class CImpIAccessor : public IAccessor
  326. {
  327. private:
  328. DEBUGCODE(ULONG m_cRef);
  329. CBaseObj *m_pObj;
  330. LPEXTBUFFER m_pextbufferAccessor; // array of accessor ptrs
  331. LPBITARRAY m_prowbitsIBuffer; // bit array to mark active rows/ or parameters
  332. BOOL m_bRowset;
  333. public:
  334. CImpIAccessor::CImpIAccessor( CBaseObj *pParentObj,BOOL bRowset = TRUE)
  335. {
  336. // Initialize simple member vars
  337. DEBUGCODE(m_cRef = 0L);
  338. m_pObj = pParentObj;
  339. m_prowbitsIBuffer = NULL;
  340. m_pextbufferAccessor= NULL;
  341. m_bRowset = bRowset;
  342. }
  343. ~CImpIAccessor()
  344. {
  345. //===============================================================
  346. // Free accessors.
  347. // Each accessor is allocated via new/delete.
  348. // We store an array of ptrs to each accessor (m_pextbufferAccessor).
  349. //===============================================================
  350. if (NULL != m_pextbufferAccessor){
  351. HACCESSOR hAccessor, hAccessorLast;
  352. PACCESSOR pAccessor;
  353. m_pextbufferAccessor->GetFirstLastItemH( hAccessor, hAccessorLast );
  354. for (; hAccessor <= hAccessorLast; hAccessor++){
  355. m_pextbufferAccessor->GetItemOfExtBuffer( hAccessor, &pAccessor );
  356. SAFE_DELETE_PTR( pAccessor );
  357. }
  358. DeleteAccessorBuffer();
  359. }
  360. // Delete bit array that marks referenced parameters.
  361. DeleteBitArray();
  362. }
  363. HRESULT CImpIAccessor::FInit();
  364. inline CBaseObj* GetBaseObjectPtr() { return m_pObj;}
  365. STDMETHODIMP_(ULONG) AddRef(void)
  366. {
  367. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  368. return m_pObj->GetOuterUnknown()->AddRef();
  369. }
  370. STDMETHODIMP_(ULONG) Release(void)
  371. {
  372. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  373. if( lRef < 0 ){
  374. ASSERT("Reference count on Object went below 0!")
  375. })
  376. return m_pObj->GetOuterUnknown()->Release();
  377. }
  378. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  379. {
  380. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  381. }
  382. STDMETHODIMP AddRefAccessor(HACCESSOR hAccessor, DBREFCOUNT* pcRefCounts);
  383. STDMETHODIMP CreateAccessor(DBACCESSORFLAGS, DBCOUNTITEM, const DBBINDING[], DBLENGTH, HACCESSOR*, DBBINDSTATUS[]);
  384. STDMETHODIMP GetBindings(HACCESSOR, DBACCESSORFLAGS*, DBCOUNTITEM*, DBBINDING**);
  385. STDMETHODIMP ReleaseAccessor(HACCESSOR, DBREFCOUNT*);
  386. // utility member functions
  387. LPBITARRAY GetBitArrayPtr() { return m_prowbitsIBuffer; }
  388. LPEXTBUFFER GetAccessorPtr() { return m_pextbufferAccessor;} // array of accessor ptrs
  389. BOOL CreateNewBitArray();
  390. BOOL CreateNewAccessorBuffer();
  391. void DeleteBitArray() { SAFE_DELETE_PTR(m_prowbitsIBuffer);}
  392. void DeleteAccessorBuffer() { SAFE_DELETE_PTR(m_pextbufferAccessor);}
  393. };
  394. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  395. class CImpIRowsetInfo : public IRowsetInfo
  396. {
  397. private:
  398. DEBUGCODE(ULONG m_cRef);
  399. CRowset *m_pObj;
  400. public:
  401. CImpIRowsetInfo( CRowset *pObj )
  402. {
  403. DEBUGCODE(m_cRef = 0L);
  404. m_pObj = pObj;
  405. }
  406. ~CImpIRowsetInfo()
  407. {
  408. }
  409. STDMETHODIMP_(ULONG) AddRef(void)
  410. {
  411. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  412. return m_pObj->GetOuterUnknown()->AddRef();
  413. }
  414. STDMETHODIMP_(ULONG) Release(void)
  415. {
  416. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  417. if( lRef < 0 ){
  418. ASSERT("Reference count on Object went below 0!")
  419. })
  420. return m_pObj->GetOuterUnknown()->Release();
  421. }
  422. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  423. {
  424. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  425. }
  426. STDMETHODIMP GetReferencedRowset
  427. (
  428. DBORDINAL iOrdinal,
  429. REFIID rrid,
  430. IUnknown** ppReferencedRowset
  431. );
  432. STDMETHODIMP GetProperties
  433. (
  434. const ULONG cPropertySets,
  435. const DBPROPIDSET rgPropertySets[],
  436. ULONG* pcProperties,
  437. DBPROPSET** prgProperties
  438. );
  439. STDMETHODIMP GetSpecification(REFIID, IUnknown**);
  440. };
  441. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  442. class CImpIRowsetIdentity : public IRowsetIdentity
  443. {
  444. private:
  445. DEBUGCODE(ULONG m_cRef);
  446. CRowset *m_pObj;
  447. public:
  448. CImpIRowsetIdentity( CRowset *pObj)
  449. {
  450. DEBUGCODE(m_cRef = 0L);
  451. m_pObj = pObj;
  452. }
  453. ~CImpIRowsetIdentity()
  454. {
  455. }
  456. STDMETHODIMP_(ULONG) AddRef(void)
  457. {
  458. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  459. return m_pObj->GetOuterUnknown()->AddRef();
  460. }
  461. STDMETHODIMP_(ULONG) Release(void)
  462. {
  463. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  464. if( lRef < 0 ){
  465. ASSERT("Reference count on Object went below 0!")
  466. })
  467. return m_pObj->GetOuterUnknown()->Release();
  468. }
  469. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  470. {
  471. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  472. }
  473. STDMETHODIMP IsSameRow( HROW hThisRow,
  474. HROW hThatRow);
  475. };
  476. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  477. class CImpIConvertType : public IConvertType
  478. {
  479. private:
  480. DEBUGCODE(ULONG m_cRef);
  481. CBaseObj *m_pObj;
  482. public:
  483. CImpIConvertType( CBaseObj *pObj )
  484. {
  485. DEBUGCODE(m_cRef = 0L);
  486. m_pObj = pObj;
  487. }
  488. ~CImpIConvertType()
  489. {
  490. }
  491. STDMETHODIMP_(ULONG) AddRef(void)
  492. {
  493. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  494. return m_pObj->GetOuterUnknown()->AddRef();
  495. }
  496. STDMETHODIMP_(ULONG) Release(void)
  497. {
  498. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  499. if( lRef < 0 ){
  500. ASSERT("Reference count on Object went below 0!")
  501. })
  502. return m_pObj->GetOuterUnknown()->Release();
  503. }
  504. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  505. {
  506. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  507. }
  508. STDMETHODIMP CImpIConvertType::CanConvert
  509. (
  510. DBTYPE wFromType, //@parm IN | src type
  511. DBTYPE wToType, //@parm IN | dst type
  512. DBCONVERTFLAGS dwConvertFlags //@parm IN | conversion flags
  513. );
  514. };
  515. class CImpIChapteredRowset : public IChapteredRowset
  516. {
  517. private:
  518. DEBUGCODE(ULONG m_cRef);
  519. CRowset *m_pObj;
  520. public:
  521. CImpIChapteredRowset( CRowset *pObj )
  522. {
  523. DEBUGCODE(m_cRef = 0L);
  524. m_pObj = pObj;
  525. }
  526. ~CImpIChapteredRowset()
  527. {
  528. }
  529. STDMETHODIMP_(ULONG) AddRef(void)
  530. {
  531. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  532. return m_pObj->GetOuterUnknown()->AddRef();
  533. }
  534. STDMETHODIMP_(ULONG) Release(void)
  535. {
  536. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  537. if( lRef < 0 ){
  538. ASSERT("Reference count on Object went below 0!")
  539. })
  540. return m_pObj->GetOuterUnknown()->Release();
  541. }
  542. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  543. {
  544. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  545. }
  546. STDMETHODIMP AddRefChapter (HCHAPTER hChapter, DBREFCOUNT * pcRefCount);
  547. STDMETHODIMP ReleaseChapter (HCHAPTER hChapter,DBREFCOUNT * pcRefCount);
  548. };
  549. class CImpIGetRow : public IGetRow
  550. {
  551. private:
  552. DEBUGCODE(ULONG m_cRef);
  553. CRowset *m_pObj;
  554. public:
  555. CImpIGetRow( CRowset *pObj )
  556. {
  557. DEBUGCODE(m_cRef = 0L);
  558. m_pObj = pObj;
  559. }
  560. ~CImpIGetRow()
  561. {
  562. }
  563. STDMETHODIMP_(ULONG) AddRef(void)
  564. {
  565. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  566. return m_pObj->GetOuterUnknown()->AddRef();
  567. }
  568. STDMETHODIMP_(ULONG) Release(void)
  569. {
  570. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  571. if( lRef < 0 ){
  572. ASSERT("Reference count on Object went below 0!")
  573. })
  574. return m_pObj->GetOuterUnknown()->Release();
  575. }
  576. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  577. {
  578. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  579. }
  580. STDMETHODIMP GetRowFromHROW(IUnknown * pUnkOuter,HROW hRow,REFIID riid,IUnknown ** ppUnk);
  581. STDMETHODIMP GetURLFromHROW(HROW hRow,LPOLESTR * ppwszURL);
  582. };
  583. class CImplIRowsetRefresh : public IRowsetRefresh
  584. {
  585. private:
  586. DEBUGCODE(ULONG m_cRef);
  587. CRowset *m_pObj;
  588. HRESULT CheckIfRowsExists(DBCOUNTITEM cRows,const HROW rghRows[],DBROWSTATUS * prgRowStatus);
  589. public:
  590. CImplIRowsetRefresh( CRowset *pObj )
  591. {
  592. DEBUGCODE(m_cRef = 0L);
  593. m_pObj = pObj;
  594. }
  595. ~CImplIRowsetRefresh()
  596. {
  597. }
  598. STDMETHODIMP_(ULONG) AddRef(void)
  599. {
  600. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  601. return m_pObj->GetOuterUnknown()->AddRef();
  602. }
  603. STDMETHODIMP_(ULONG) Release(void)
  604. {
  605. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  606. if( lRef < 0 ){
  607. ASSERT("Reference count on Object went below 0!")
  608. })
  609. return m_pObj->GetOuterUnknown()->Release();
  610. }
  611. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  612. {
  613. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  614. }
  615. STDMETHODIMP GetLastVisibleData(HROW hRow,HACCESSOR hAccessor,void * pData);
  616. STDMETHODIMP RefreshVisibleData(HCHAPTER hChapter,
  617. DBCOUNTITEM cRows,
  618. const HROW rghRows[],
  619. BOOL fOverwrite,
  620. DBCOUNTITEM * pcRowsRefreshed,
  621. HROW ** prghRowsRefreshed,
  622. DBROWSTATUS ** prgRowStatus);
  623. };
  624. class CImplIParentRowset:public IParentRowset
  625. {
  626. private:
  627. DEBUGCODE(ULONG m_cRef);
  628. CRowset *m_pObj;
  629. public:
  630. CImplIParentRowset( CRowset *pObj )
  631. {
  632. DEBUGCODE(m_cRef = 0L);
  633. m_pObj = pObj;
  634. }
  635. ~CImplIParentRowset()
  636. {
  637. }
  638. STDMETHODIMP_(ULONG) AddRef(void)
  639. {
  640. DEBUGCODE(InterlockedIncrement((long*)&m_cRef));
  641. return m_pObj->GetOuterUnknown()->AddRef();
  642. }
  643. STDMETHODIMP_(ULONG) Release(void)
  644. {
  645. DEBUGCODE(long lRef = InterlockedDecrement((long*)&m_cRef);
  646. if( lRef < 0 ){
  647. ASSERT("Reference count on Object went below 0!")
  648. })
  649. return m_pObj->GetOuterUnknown()->Release();
  650. }
  651. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv)
  652. {
  653. return m_pObj->GetOuterUnknown()->QueryInterface(riid, ppv);
  654. }
  655. STDMETHODIMP GetChildRowset( IUnknown __RPC_FAR *pUnkOuter,
  656. DBORDINAL iOrdinal,
  657. REFIID riid,
  658. IUnknown __RPC_FAR *__RPC_FAR *ppRowset);
  659. };
  660. // class for storing instance information for each row in rowset
  661. class CWMIInstance
  662. {
  663. public:
  664. CWbemClassWrapper * m_pInstance;
  665. HROW m_hRow;
  666. HSLOT m_hSlot;
  667. CWMIInstance * m_pNext;
  668. BSTR m_strKey;
  669. DBSTATUS m_dwStatus;
  670. CWMIInstance()
  671. {
  672. m_pInstance = NULL;
  673. m_hRow = DBROWSTATUS_S_OK;
  674. m_pNext = NULL;
  675. m_hSlot = -1;
  676. m_strKey = Wmioledb_SysAllocString(NULL);
  677. m_dwStatus = 0;
  678. }
  679. ~CWMIInstance()
  680. {
  681. if(m_strKey)
  682. {
  683. SysFreeString(m_strKey);
  684. }
  685. }
  686. void SetRowStatus(DBSTATUS dwStatus) { m_dwStatus = dwStatus ; };
  687. DBSTATUS GetRowStatus() { return m_dwStatus; };
  688. };
  689. // class to maps HROWS to CWMIInstance
  690. class CWMIInstanceMgr
  691. {
  692. private:
  693. ULONG m_lCount; // count of instances in the list;
  694. public:
  695. CWMIInstance *m_pFirst;
  696. CWMIInstanceMgr();
  697. ~CWMIInstanceMgr();
  698. HRESULT AddInstanceToList(HROW hRow ,CWbemClassWrapper *pInstance ,BSTR strKey, HSLOT hSlot = -1);
  699. HRESULT DeleteInstanceFromList(HROW hRow);
  700. CWbemClassWrapper * GetInstance(HROW hRow);
  701. HRESULT GetInstanceKey(HROW hRow, BSTR * strKey);
  702. HRESULT GetAllHROWs(HROW *&prghRows , DBCOUNTITEM &cRows);
  703. HRESULT SetSlot(HROW hRow , HSLOT hSlot);
  704. HSLOT GetSlot(HROW hRow);
  705. BOOL IsRowExists(HROW hrow);
  706. BOOL IsInstanceExist(BSTR strKey);
  707. BOOL IsInstanceExist(CWbemClassWrapper *pInstance);
  708. HROW GetHRow(BSTR strKey);
  709. void SetRowStatus(HROW hRow , DBSTATUS dwStatus);
  710. DBSTATUS GetRowStatus(HROW hRow);
  711. };
  712. //=================================================================
  713. //Abstract base class for fetching rows and data for rows
  714. //=================================================================
  715. class CRowFetchObj
  716. {
  717. void ClearRowBuffer(void *pData,DBBINDING *pBinding,int nCurCol);
  718. protected:
  719. LONG_PTR GetFirstFetchPos(CRowset *pRowset,DBCOUNTITEM cRows,DBROWOFFSET lOffset);
  720. public:
  721. virtual HRESULT FetchRows( CRowset * pRowset,
  722. HCHAPTER hChapter, // IN The Chapter handle.
  723. DBROWOFFSET lRowOffset, // IN Rows to skip before reading
  724. DBROWCOUNT cRows, // IN Number of rows to fetch
  725. DBCOUNTITEM* pcRowsObtained, // OUT Number of rows obtained
  726. HROW ** prghRows) = 0; // OUT Array of Hrows obtained)
  727. virtual HRESULT FetchData(CRowset * pRowset,
  728. HROW hRow, //IN Row Handle
  729. HACCESSOR hAccessor, //IN Accessor to use
  730. void *pData ) ;
  731. HRESULT CRowFetchObj::FetchRowsByBookMark(CRowset * pRowset,
  732. HCHAPTER hChapter, // IN The Chapter handle.
  733. DBROWCOUNT cRows, // IN Number of rows to fetch
  734. const DBBKMARK rgcbBookmarks[], //@parm IN | an array of bookmark sizes
  735. const BYTE* rgpBookmarks[], //@parm IN | an array of pointers to bookmarks
  736. HROW rghRows[], // OUT Array of Hrows obtained
  737. DBROWSTATUS rgRowStatus[]); // OUT status of rows
  738. HRESULT CRowFetchObj::FetchNextRowsByBookMark(CRowset * pRowset,
  739. HCHAPTER hChapter, // IN The Chapter handle.
  740. DBBKMARK cbBookmark, // size of BOOKMARK
  741. const BYTE * pBookmark, // The bookmark from which fetch should start
  742. DBROWOFFSET lRowsOffset,
  743. DBROWCOUNT cRows,
  744. DBCOUNTITEM * pcRowsObtained,
  745. HROW ** prghRows);
  746. };
  747. //=====================================================================
  748. // Row fetch object for fetching data for rowsets showing instance
  749. //=====================================================================
  750. class CInstanceRowFetchObj : public CRowFetchObj
  751. {
  752. public:
  753. virtual HRESULT FetchRows( CRowset * pRowset,
  754. HCHAPTER hChapter, // IN The Chapter handle.
  755. DBROWOFFSET lRowOffset, // IN Rows to skip before reading
  756. DBROWCOUNT cRows, // IN Number of rows to fetch
  757. DBCOUNTITEM*pcRowsObtained, // OUT Number of rows obtained
  758. HROW **prghRows); // OUT Array of Hrows obtained)
  759. };
  760. //=====================================================================
  761. // Row fetch object for fetching data for rowsets qualifiers
  762. //=====================================================================
  763. class CQualifierRowFetchObj : public CRowFetchObj
  764. {
  765. public:
  766. virtual HRESULT FetchRows( CRowset * pRowset,
  767. HCHAPTER hChapter, // IN The Chapter handle.
  768. DBROWOFFSET lRowOffset, // IN Rows to skip before reading
  769. DBROWCOUNT cRows, // IN Number of rows to fetch
  770. DBCOUNTITEM*pcRowsObtained, // OUT Number of rows obtained
  771. HROW ** prghRows); // OUT Array of Hrows obtained)
  772. };
  773. inline BOOL CRowset::BitArrayInitialized()
  774. { return ((LPBITARRAY)m_pIAccessor->GetBitArrayPtr()) == NULL ? FALSE : TRUE; }
  775. inline LPEXTBUFFER CRowset::GetAccessorBuffer()
  776. { return (LPEXTBUFFER)m_pIAccessor->GetAccessorPtr(); }
  777. #endif