Leaked source code of windows server 2003
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.

346 lines
8.9 KiB

  1. //--------------------------------------------------------------------------
  2. // EnumMsgs.cpp
  3. //--------------------------------------------------------------------------
  4. #include "pch.hxx"
  5. #include "enummsgs.h"
  6. //--------------------------------------------------------------------------
  7. // CEnumerateMessages::CEnumerateMessages
  8. //--------------------------------------------------------------------------
  9. CEnumerateMessages::CEnumerateMessages(void)
  10. {
  11. TraceCall("CEnumerateMessages::CEnumerateMessages");
  12. m_cRef = 1;
  13. m_hRowset = NULL;
  14. m_pDB = NULL;
  15. m_idParent = MESSAGEID_INVALID;
  16. }
  17. //--------------------------------------------------------------------------
  18. // CEnumerateMessages::~CEnumerateMessages
  19. //--------------------------------------------------------------------------
  20. CEnumerateMessages::~CEnumerateMessages(void)
  21. {
  22. TraceCall("CEnumerateMessages::~CEnumerateMessages");
  23. if (m_hRowset && m_pDB)
  24. m_pDB->CloseRowset(&m_hRowset);
  25. SafeRelease(m_pDB);
  26. }
  27. //--------------------------------------------------------------------------
  28. // CEnumerateMessages::QueryInterface
  29. //--------------------------------------------------------------------------
  30. STDMETHODIMP CEnumerateMessages::QueryInterface(REFIID riid, LPVOID *ppv)
  31. {
  32. // Locals
  33. HRESULT hr=S_OK;
  34. // Stack
  35. TraceCall("CEnumerateMessages::QueryInterface");
  36. // Find IID
  37. if (IID_IUnknown == riid)
  38. *ppv = (IUnknown *)this;
  39. else
  40. {
  41. *ppv = NULL;
  42. hr = TraceResult(E_NOINTERFACE);
  43. goto exit;
  44. }
  45. // AddRef It
  46. ((IUnknown *)*ppv)->AddRef();
  47. exit:
  48. // Done
  49. return(hr);
  50. }
  51. //--------------------------------------------------------------------------
  52. // CEnumerateMessages::AddRef
  53. //--------------------------------------------------------------------------
  54. STDMETHODIMP_(ULONG) CEnumerateMessages::AddRef(void)
  55. {
  56. TraceCall("CEnumerateMessages::AddRef");
  57. return InterlockedIncrement(&m_cRef);
  58. }
  59. //--------------------------------------------------------------------------
  60. // CEnumerateMessages::Release
  61. //--------------------------------------------------------------------------
  62. STDMETHODIMP_(ULONG) CEnumerateMessages::Release(void)
  63. {
  64. TraceCall("CEnumerateMessages::Release");
  65. LONG cRef = InterlockedDecrement(&m_cRef);
  66. if (0 == cRef)
  67. delete this;
  68. return (ULONG)cRef;
  69. }
  70. //--------------------------------------------------------------------------
  71. // CEnumerateMessages::Initialize
  72. //--------------------------------------------------------------------------
  73. HRESULT CEnumerateMessages::Initialize(IDatabase *pDB, MESSAGEID idParent)
  74. {
  75. // Locals
  76. HRESULT hr=S_OK;
  77. MESSAGEINFO Child={0};
  78. ROWORDINAL iFirstRow;
  79. // Trace
  80. TraceCall("CEnumerateMessages::Initialize");
  81. // Invalid Args
  82. Assert(pDB);
  83. // Reset ?
  84. if (m_hRowset && m_pDB)
  85. m_pDB->CloseRowset(&m_hRowset);
  86. SafeRelease(m_pDB);
  87. // Save parent
  88. m_idParent = idParent;
  89. // Save pStore
  90. m_pDB = pDB;
  91. m_pDB->AddRef();
  92. // Set idParent
  93. Child.idParent = idParent;
  94. // Locate where the first record with idParent
  95. IF_FAILEXIT(hr = m_pDB->FindRecord(IINDEX_THREADS, 1, &Child, &iFirstRow));
  96. // Not Found
  97. if (DB_S_NOTFOUND == hr)
  98. {
  99. hr = S_OK;
  100. goto exit;
  101. }
  102. // Create a Rowset
  103. IF_FAILEXIT(hr = m_pDB->CreateRowset(IINDEX_THREADS, NOFLAGS, &m_hRowset));
  104. // Seek the rowset to the first row
  105. IF_FAILEXIT(hr = m_pDB->SeekRowset(m_hRowset, SEEK_ROWSET_BEGIN, iFirstRow - 1, NULL));
  106. exit:
  107. // Cleanup
  108. m_pDB->FreeRecord(&Child);
  109. // Done
  110. return(hr);
  111. }
  112. //--------------------------------------------------------------------------
  113. // CEnumerateMessages::Next
  114. //--------------------------------------------------------------------------
  115. STDMETHODIMP CEnumerateMessages::Next(ULONG cWanted, LPMESSAGEINFO prgInfo,
  116. ULONG *pcFetched)
  117. {
  118. // Locals
  119. HRESULT hr=S_OK;
  120. DWORD cFetched=0;
  121. // Trace
  122. TraceCall("CEnumerateMessages::Next");
  123. // Initialize
  124. if (pcFetched)
  125. *pcFetched = 0;
  126. // Nothing
  127. if (NULL == m_hRowset)
  128. return(S_FALSE);
  129. // Validate
  130. Assert(m_pDB);
  131. // Query the Rowset for cFetch Rows...
  132. IF_FAILEXIT(hr = m_pDB->QueryRowset(m_hRowset, cWanted, (LPVOID *)prgInfo, &cFetched));
  133. // Adjust Actual Fetched based on m_idParent
  134. while(cFetched && prgInfo[cFetched - 1].idParent != m_idParent)
  135. {
  136. // Free prgInfo
  137. m_pDB->FreeRecord(&prgInfo[cFetched - 1]);
  138. // Decrement cFetched
  139. cFetched--;
  140. }
  141. // Return pcFetched
  142. if (pcFetched)
  143. *pcFetched = cFetched;
  144. exit:
  145. // Done
  146. return(cFetched == cWanted) ? S_OK : S_FALSE;
  147. }
  148. //--------------------------------------------------------------------------
  149. // CEnumerateMessages::Skip
  150. //--------------------------------------------------------------------------
  151. STDMETHODIMP CEnumerateMessages::Skip(ULONG cItems)
  152. {
  153. // Locals
  154. HRESULT hr=S_OK;
  155. DWORD i;
  156. MESSAGEINFO Message={0};
  157. // Trace
  158. TraceCall("CEnumerateMessages::Skip");
  159. // Loop...
  160. for (i=0; i<cItems; i++)
  161. {
  162. // Query the Rowset for cFetch Rows...
  163. IF_FAILEXIT(hr = m_pDB->QueryRowset(m_hRowset, 1, (LPVOID *)&Message, NULL));
  164. // Different Parent
  165. if (Message.idParent != m_idParent)
  166. break;
  167. // Free
  168. m_pDB->FreeRecord(&Message);
  169. }
  170. exit:
  171. // Free
  172. m_pDB->FreeRecord(&Message);
  173. // Done
  174. return(hr);
  175. }
  176. //--------------------------------------------------------------------------
  177. // CEnumerateMessages::Reset
  178. //--------------------------------------------------------------------------
  179. STDMETHODIMP CEnumerateMessages::Reset(void)
  180. {
  181. // Locals
  182. HRESULT hr=S_OK;
  183. MESSAGEINFO Child={0};
  184. ROWORDINAL iFirstRow;
  185. // Trace
  186. TraceCall("CEnumerateMessages::Reset");
  187. // Close Rowset
  188. m_pDB->CloseRowset(&m_hRowset);
  189. // Set idParent
  190. Child.idParent = m_idParent;
  191. // Locate where the first record with idParent
  192. IF_FAILEXIT(hr = m_pDB->FindRecord(IINDEX_THREADS, 1, &Child, &iFirstRow));
  193. // Not Found
  194. if (DB_S_NOTFOUND == hr)
  195. {
  196. hr = S_OK;
  197. goto exit;
  198. }
  199. // Create a Rowset
  200. IF_FAILEXIT(hr = m_pDB->CreateRowset(IINDEX_THREADS, NOFLAGS, &m_hRowset));
  201. // Seek the rowset to the first row
  202. IF_FAILEXIT(hr = m_pDB->SeekRowset(m_hRowset, SEEK_ROWSET_BEGIN, iFirstRow - 1, NULL));
  203. exit:
  204. // Cleanup
  205. m_pDB->FreeRecord(&Child);
  206. // Done
  207. return(hr);
  208. }
  209. //--------------------------------------------------------------------------
  210. // CEnumerateMessages::Clone
  211. //--------------------------------------------------------------------------
  212. STDMETHODIMP CEnumerateMessages::Clone(CEnumerateMessages **ppEnum)
  213. {
  214. // Locals
  215. HRESULT hr=S_OK;
  216. CEnumerateMessages *pEnum=NULL;
  217. // Trace
  218. TraceCall("CEnumerateMessages::Clone");
  219. // Allocate a New Enumerator
  220. IF_NULLEXIT(pEnum = new CEnumerateMessages);
  221. // Initialzie
  222. IF_FAILEXIT(hr = pEnum->Initialize(m_pDB, m_idParent));
  223. // Return It
  224. *ppEnum = (CEnumerateMessages *)pEnum;
  225. // Don't Release It
  226. pEnum = NULL;
  227. exit:
  228. // Cleanup
  229. SafeRelease(pEnum);
  230. // Done
  231. return(hr);
  232. }
  233. //--------------------------------------------------------------------------
  234. // CEnumerateMessages::Release
  235. //--------------------------------------------------------------------------
  236. STDMETHODIMP CEnumerateMessages::Count(ULONG *pcItems)
  237. {
  238. // Locals
  239. HRESULT hr=S_OK;
  240. MESSAGEINFO Child={0};
  241. MESSAGEINFO Message={0};
  242. ROWORDINAL iFirstRow;
  243. HROWSET hRowset;
  244. // Trace
  245. TraceCall("CEnumerateMessages::Next");
  246. // Init
  247. *pcItems = 0;
  248. // Set idParent
  249. Child.idParent = m_idParent;
  250. // Locate where the first record with idParent
  251. IF_FAILEXIT(hr = m_pDB->FindRecord(IINDEX_THREADS, 1, &Child, &iFirstRow));
  252. // Not Found
  253. if (DB_S_NOTFOUND == hr)
  254. {
  255. hr = S_OK;
  256. goto exit;
  257. }
  258. // Create a Rowset
  259. IF_FAILEXIT(hr = m_pDB->CreateRowset(IINDEX_THREADS, NOFLAGS, &hRowset));
  260. // Seek the rowset to the first row
  261. IF_FAILEXIT(hr = m_pDB->SeekRowset(hRowset, SEEK_ROWSET_BEGIN, iFirstRow - 1, NULL));
  262. // Walk the Rowset
  263. while (S_OK == m_pDB->QueryRowset(hRowset, 1, (LPVOID *)&Message, NULL) && Message.idParent == m_idParent)
  264. {
  265. // Increment Count
  266. (*pcItems)++;
  267. // Free
  268. m_pDB->FreeRecord(&Message);
  269. }
  270. exit:
  271. // Cleanup
  272. m_pDB->CloseRowset(&hRowset);
  273. m_pDB->FreeRecord(&Message);
  274. m_pDB->FreeRecord(&Child);
  275. // Done
  276. return(hr);
  277. }