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.

577 lines
12 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. FaxMessageIteratorInner.h
  5. Abstract:
  6. Implementation of Fax Message Iterator Inner Class :
  7. Base Class for Inbound and Outbound Message Iterators Classes.
  8. Author:
  9. Iv Garber (IvG) May, 2000
  10. Revision History:
  11. --*/
  12. #ifndef __FAXMESSAGEITERATORINNER_H_
  13. #define __FAXMESSAGEITERATORINNER_H_
  14. #include "FaxCommon.h"
  15. //
  16. //===================== FAX MESSAGE ITERATOR INNER CLASS ===============================
  17. //
  18. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  19. class MsgIfc, class MsgType>
  20. class CFaxMessageIteratorInner :
  21. public IDispatchImpl<T, piid, &LIBID_FAXCOMEXLib>,
  22. public CFaxInitInnerAddRef
  23. {
  24. public:
  25. CFaxMessageIteratorInner() : CFaxInitInnerAddRef(_T("FAX MESSAGE ITERATOR INNER")),
  26. m_dwPrefetchSize(prv_DEFAULT_PREFETCH_SIZE),
  27. m_hEnum(NULL)
  28. {};
  29. virtual ~CFaxMessageIteratorInner()
  30. {
  31. DBG_ENTER(_T("CFaxMessageIteratorInner::Dtor"));
  32. if (m_hEnum)
  33. {
  34. //
  35. // Close currently active Enumeration
  36. //
  37. FaxEndMessagesEnum(m_hEnum);
  38. }
  39. }
  40. STDMETHOD(get_PrefetchSize)(/*[out, retval]*/ long *plPrefetchSize);
  41. STDMETHOD(put_PrefetchSize)(/*[in]*/ long lPrefetchSize);
  42. STDMETHOD(get_AtEOF)(/*[out, retval]*/ VARIANT_BOOL *pbEOF);
  43. STDMETHOD(MoveFirst)();
  44. STDMETHOD(MoveNext)();
  45. STDMETHOD(get_Message)(MsgIfc **ppMessage);
  46. private:
  47. DWORD m_dwPrefetchSize;
  48. HANDLE m_hEnum;
  49. CFaxPtr<FAX_MESSAGE> m_pMsgList;
  50. DWORD m_dwTotalMsgNum;
  51. DWORD m_dwCurMsgNum;
  52. private:
  53. HRESULT RetrieveMessages();
  54. HRESULT SetEOF();
  55. };
  56. //
  57. //====================== GET PREFETCH SIZE ================================================
  58. //
  59. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  60. class MsgIfc, class MsgType>
  61. STDMETHODIMP
  62. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::get_PrefetchSize(
  63. long *plPrefetchSize
  64. )
  65. /*++
  66. Routine name : CFaxMessageIteratorInner::get_PrefetchSize
  67. Routine description:
  68. Return current Prefetch Size value
  69. Author:
  70. Iv Garber (IvG), May, 2000
  71. Arguments:
  72. plPrefetchSize [out] - pointer to the place to put the PrefetchSize value
  73. Return Value:
  74. Standard HRESULT code
  75. --*/
  76. {
  77. HRESULT hr = S_OK;
  78. DBG_ENTER (TEXT("CFaxMessageInner::get_PrefetchSize"), hr);
  79. hr = GetLong(plPrefetchSize, m_dwPrefetchSize);
  80. if (FAILED(hr))
  81. {
  82. AtlReportError(*pcid, GetErrorMsgId(hr), *piid, hr);
  83. return hr;
  84. }
  85. return hr;
  86. }
  87. //
  88. //====================== PUT PREFETCH SIZE ================================================
  89. //
  90. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  91. class MsgIfc, class MsgType>
  92. STDMETHODIMP
  93. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::put_PrefetchSize(
  94. long lPrefetchSize
  95. )
  96. /*++
  97. Routine name : CFaxMessageIteratorInner::put_PrefetchSize
  98. Routine description:
  99. Set the Prefetch Size
  100. Author:
  101. Iv Garber (IvG), May, 2000
  102. Arguments:
  103. lPrefetchSize [in] - the value of the Prefetch Size to set
  104. Return Value:
  105. Standard HRESULT code
  106. --*/
  107. {
  108. HRESULT hr = S_OK;
  109. DBG_ENTER (TEXT("CFaxMessageInner::put_PrefetchSize"), hr, _T("%ld"), lPrefetchSize);
  110. //
  111. // Check that lPrefetchSize is valid
  112. //
  113. if (lPrefetchSize < 1)
  114. {
  115. //
  116. // illegal value
  117. //
  118. hr = E_INVALIDARG;
  119. AtlReportError(*pcid, IDS_ERROR_ZERO_PREFETCHSIZE, *piid, hr);
  120. CALL_FAIL(GENERAL_ERR, _T("lPrefetchSize < 1"), hr);
  121. return hr;
  122. }
  123. m_dwPrefetchSize = lPrefetchSize;
  124. return hr;
  125. }
  126. //
  127. //====================== GET AtEOF ====================================================
  128. //
  129. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  130. class MsgIfc, class MsgType>
  131. STDMETHODIMP
  132. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::get_AtEOF(
  133. VARIANT_BOOL *pbEOF
  134. )
  135. /*++
  136. Routine name : CFaxMessageIteratorInner::get_EOF
  137. Routine description:
  138. Return EOF value
  139. Author:
  140. Iv Garber (IvG), May, 2000
  141. Arguments:
  142. pbEOF [out] - pointer to the place to put the EOF value
  143. Return Value:
  144. Standard HRESULT code
  145. --*/
  146. {
  147. HRESULT hr = S_OK;
  148. DBG_ENTER (TEXT("CFaxMessageInner::get_EOF"), hr);
  149. //
  150. // If not yet, start Enumeration
  151. //
  152. if (!m_hEnum)
  153. {
  154. hr = MoveFirst();
  155. if (FAILED(hr))
  156. {
  157. return hr;
  158. }
  159. }
  160. hr = GetVariantBool(pbEOF, ((m_pMsgList) ? VARIANT_FALSE : VARIANT_TRUE));
  161. if (FAILED(hr))
  162. {
  163. AtlReportError(*pcid, GetErrorMsgId(hr), *piid, hr);
  164. return hr;
  165. }
  166. return hr;
  167. }
  168. //
  169. //====================== MOVE FIRST ================================================
  170. //
  171. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  172. class MsgIfc, class MsgType>
  173. STDMETHODIMP
  174. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::MoveFirst(
  175. )
  176. /*++
  177. Routine name : CFaxMessageIteratorInner::MoveFirst
  178. Routine description:
  179. Start New Enumeration
  180. Author:
  181. Iv Garber (IvG), May, 2000
  182. Return Value:
  183. Standard HRESULT code
  184. --*/
  185. {
  186. HRESULT hr = S_OK;
  187. DBG_ENTER (TEXT("CFaxMessageIteratorInner::MoveFirst"), hr);
  188. //
  189. // Clear current Msg List
  190. //
  191. SetEOF();
  192. if (m_hEnum)
  193. {
  194. //
  195. // Enumeration already started. Close it before starting new one
  196. //
  197. if (!FaxEndMessagesEnum(m_hEnum))
  198. {
  199. //
  200. // Failed to Stop current Enumeration
  201. //
  202. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  203. AtlReportError(*pcid, IDS_ERROR_OPERATION_FAILED, *piid, hr);
  204. CALL_FAIL(GENERAL_ERR, _T("FaxEndMessagesEnum(hEnum)"), hr);
  205. return hr;
  206. }
  207. m_hEnum = NULL;
  208. }
  209. //
  210. // Get Fax Server Handle
  211. //
  212. HANDLE hFaxHandle = NULL;
  213. hr = GetFaxHandle(&hFaxHandle);
  214. if (FAILED(hr))
  215. {
  216. AtlReportError(*pcid, IDS_ERROR_OPERATION_FAILED, *piid, hr);
  217. return hr;
  218. }
  219. //
  220. // Start new Enumeration
  221. //
  222. if (!FaxStartMessagesEnum(hFaxHandle, FolderType, &m_hEnum))
  223. {
  224. //
  225. // Failed to Start an Enumeration
  226. //
  227. DWORD dwError = GetLastError();
  228. if (ERROR_NO_MORE_ITEMS == dwError)
  229. {
  230. //
  231. // EOF case
  232. //
  233. return hr;
  234. }
  235. hr = Fax_HRESULT_FROM_WIN32(dwError);
  236. AtlReportError(*pcid, GetErrorMsgId(hr), *piid, hr);
  237. CALL_FAIL(GENERAL_ERR, _T("FaxStartMessagesEnum()"), hr);
  238. return hr;
  239. }
  240. //
  241. // Bring new Msg List
  242. //
  243. hr = RetrieveMessages();
  244. return hr;
  245. }
  246. //
  247. //====================== RETRIEVE MESSAGES ================================================
  248. //
  249. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  250. class MsgIfc, class MsgType>
  251. HRESULT
  252. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::RetrieveMessages(
  253. )
  254. /*++
  255. Routine name : CFaxMessageIteratorInner::RetrieveMessages
  256. Routine description:
  257. Retrieve Message List
  258. Author:
  259. Iv Garber (IvG), May, 2000
  260. Return Value:
  261. Standard HRESULT code
  262. --*/
  263. {
  264. HRESULT hr = S_OK;
  265. DBG_ENTER (TEXT("CFaxMessageIteratorInner::RetrieveMessages"), hr);
  266. //
  267. // Retrieve List of Messages
  268. //
  269. if (!FaxEnumMessages(m_hEnum, m_dwPrefetchSize, &m_pMsgList, &m_dwTotalMsgNum))
  270. {
  271. //
  272. // Failed to get Msg List
  273. //
  274. DWORD dwError = GetLastError();
  275. if (dwError == ERROR_NO_MORE_ITEMS)
  276. {
  277. //
  278. // EOF Case
  279. //
  280. return hr;
  281. }
  282. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  283. AtlReportError(*pcid, IDS_ERROR_OPERATION_FAILED, *piid, hr);
  284. CALL_FAIL(GENERAL_ERR, _T("FaxEnumMessages()"), hr);
  285. return hr;
  286. }
  287. ATLASSERT(m_pMsgList);
  288. return hr;
  289. }
  290. //
  291. //====================== MOVE NEXT ================================================
  292. //
  293. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  294. class MsgIfc, class MsgType>
  295. STDMETHODIMP
  296. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::MoveNext(
  297. )
  298. /*++
  299. Routine name : FolderType>::MoveNext
  300. Routine description:
  301. Move the cursor to the next Message in the List.
  302. Author:
  303. Iv Garber (IvG), May, 2000
  304. Return Value:
  305. Standard HRESULT code
  306. --*/
  307. {
  308. HRESULT hr = S_OK;
  309. DBG_ENTER (TEXT("CFaxMessageInner::MoveNext"), hr);
  310. //
  311. // If not yet, start Enumeration
  312. //
  313. if (!m_hEnum)
  314. {
  315. hr = MoveFirst();
  316. if (FAILED(hr))
  317. {
  318. return hr;
  319. }
  320. }
  321. m_dwCurMsgNum++;
  322. if (m_dwCurMsgNum == m_dwTotalMsgNum)
  323. {
  324. //
  325. // We've read all the Msg List. Let's bring next one
  326. //
  327. SetEOF();
  328. hr = RetrieveMessages();
  329. }
  330. return hr;
  331. }
  332. //
  333. //====================== SET EOF ================================================
  334. //
  335. template<class T, const IID* piid, const CLSID *pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  336. class MsgIfc, class MsgType>
  337. HRESULT
  338. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::SetEOF(
  339. )
  340. /*++
  341. Routine name : FolderType>::SetEOF
  342. Routine description:
  343. Clear all instance variables dealing with Msg List.
  344. Author:
  345. Iv Garber (IvG), May, 2000
  346. Return Value:
  347. Standard HRESULT code
  348. --*/
  349. {
  350. HRESULT hr = S_OK;
  351. DBG_ENTER (TEXT("CFaxMessageInner::SetEOF"), hr);
  352. m_dwCurMsgNum = 0;
  353. m_dwTotalMsgNum = 0;
  354. m_pMsgList.Detach();
  355. return hr;
  356. }
  357. //
  358. //====================== GET MESSAGE ================================================
  359. //
  360. //
  361. template<class T, const IID* piid, const CLSID* pcid, FAX_ENUM_MESSAGE_FOLDER FolderType,
  362. class MsgIfc, class MsgType>
  363. STDMETHODIMP
  364. CFaxMessageIteratorInner<T, piid, pcid, FolderType, MsgIfc, MsgType>::get_Message(
  365. MsgIfc **ppMessage
  366. )
  367. /*++
  368. Routine name : CFaxMessageIteratorInner::GetMessage
  369. Routine description:
  370. Return Next Message Object from the Archive
  371. Author:
  372. Iv Garber (IvG), May, 2000
  373. Arguments:
  374. ppMessage [out] - pointer to the place to put the Message Object
  375. Return Value:
  376. Standard HRESULT code
  377. --*/
  378. {
  379. HRESULT hr = S_OK;
  380. DBG_ENTER (TEXT("CFaxMessageIteratorInner::GetMessage"), hr);
  381. //
  382. // If not yet, start Enumeration
  383. //
  384. if (!m_hEnum)
  385. {
  386. hr = MoveFirst();
  387. if (FAILED(hr))
  388. {
  389. return hr;
  390. }
  391. }
  392. if (!m_pMsgList)
  393. {
  394. //
  395. // Error, we at EOF
  396. //
  397. hr = ERROR_HANDLE_EOF;
  398. AtlReportError(*pcid, IDS_ERROR_EOF, *piid, hr);
  399. CALL_FAIL(GENERAL_ERR, _T("FaxEnumMessages()"), hr);
  400. return hr;
  401. }
  402. //
  403. // Create Message Object
  404. //
  405. CComPtr<MsgIfc> pMsg;
  406. hr = MsgType::Create(&pMsg);
  407. if (FAILED(hr))
  408. {
  409. //
  410. // Failed to create Message object
  411. //
  412. AtlReportError(*pcid, IDS_ERROR_OPERATION_FAILED, *piid, hr);
  413. CALL_FAIL(GENERAL_ERR, _T("MessageClass::Create(&pMsg)"), hr);
  414. return hr;
  415. }
  416. //
  417. // Initialize the Message Object
  418. //
  419. hr = ((MsgType *)((MsgIfc *)pMsg))->Init(&m_pMsgList[m_dwCurMsgNum], m_pIFaxServerInner);
  420. if (FAILED(hr))
  421. {
  422. //
  423. // Failed to Init the Message Object
  424. //
  425. AtlReportError(*pcid, IDS_ERROR_OPERATION_FAILED, *piid, hr);
  426. CALL_FAIL(GENERAL_ERR, _T("pMsg->Init()"), hr);
  427. return hr;
  428. }
  429. //
  430. // Return Message Object to the Caller
  431. //
  432. hr = pMsg.CopyTo(ppMessage);
  433. if (FAILED(hr))
  434. {
  435. //
  436. // Failed to Copy Interface
  437. //
  438. AtlReportError(*pcid, IDS_ERROR_OPERATION_FAILED, *piid, hr);
  439. CALL_FAIL(GENERAL_ERR, _T("CComPtr::CopyTo"), hr);
  440. return hr;
  441. }
  442. return hr;
  443. }
  444. #endif // __FAXMESSAGEITERATORINNER_H_