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.

2116 lines
45 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. FaxDocument.cpp
  5. Abstract:
  6. Implementation of CFaxDocument
  7. Author:
  8. Iv Garber (IvG) Apr, 2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "FaxComEx.h"
  13. #include "FaxDocument.h"
  14. #include "faxutil.h"
  15. //
  16. //==================== SUBMIT =======================================
  17. //
  18. STDMETHODIMP
  19. CFaxDocument::Submit(
  20. /*[in]*/ BSTR bstrFaxServerName,
  21. /*[out, retval]*/ VARIANT *pvFaxOutgoingJobIDs
  22. )
  23. /*++
  24. Routine name : CFaxDocument::Submit
  25. Routine description:
  26. Connect to the Fax Server whose name is given as a parameter to the function;
  27. Submit the Fax Document on this Fax Server;
  28. Disconnect from the Fax Server.
  29. Author:
  30. Iv Garber (IvG), Dec, 2000
  31. Arguments:
  32. bstrFaxServerName [in] - Fax Server Name to connect and send the document through
  33. ppsfbstrFaxOutgoingJobIDs [out, retval] - Result : List of Created Jobs for the Document
  34. Return Value:
  35. Standard HRESULT code
  36. --*/
  37. {
  38. HRESULT hr = S_OK;
  39. DBG_ENTER (_T("CFaxDocument::Submit"), hr, _T("%s"), bstrFaxServerName);
  40. //
  41. // Create Fax Server Object
  42. //
  43. CComObject<CFaxServer> *pFaxServer = NULL;
  44. hr = CComObject<CFaxServer>::CreateInstance(&pFaxServer);
  45. if (FAILED(hr) || !pFaxServer)
  46. {
  47. //
  48. // Not enough memory
  49. //
  50. hr = E_OUTOFMEMORY;
  51. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  52. CALL_FAIL(MEM_ERR, _T("new CComObject<CFaxServer>"), hr);
  53. goto exit;
  54. }
  55. pFaxServer->AddRef();
  56. //
  57. // Connect to Fax Server
  58. //
  59. hr = pFaxServer->Connect(bstrFaxServerName);
  60. if (FAILED(hr))
  61. {
  62. //
  63. // Connect handles the error
  64. //
  65. CALL_FAIL(GENERAL_ERR, _T("faxServer.Connect()"), hr);
  66. goto exit;
  67. }
  68. //
  69. // Submit Fax Document
  70. //
  71. hr = ConnectedSubmit(pFaxServer, pvFaxOutgoingJobIDs);
  72. if (FAILED(hr))
  73. {
  74. //
  75. // Submit handles the error
  76. //
  77. CALL_FAIL(GENERAL_ERR, _T("Submit(faxServer,...)"), hr);
  78. goto exit;
  79. }
  80. //
  81. // Disconnect
  82. //
  83. hr = pFaxServer->Disconnect();
  84. if (FAILED(hr))
  85. {
  86. //
  87. // Disconnect handles the error
  88. //
  89. CALL_FAIL(GENERAL_ERR, _T("faxServer.Disconnect())"), hr);
  90. }
  91. exit:
  92. if (pFaxServer)
  93. {
  94. pFaxServer->Release();
  95. }
  96. return hr;
  97. }
  98. //
  99. //================= FINAL CONSTRUCT ===========================
  100. //
  101. HRESULT
  102. CFaxDocument::FinalConstruct()
  103. /*++
  104. Routine name : CFaxDocument::FinalConstruct
  105. Routine description:
  106. Final Construct
  107. Author:
  108. Iv Garber (IvG), Apr, 2000
  109. Arguments:
  110. Return Value:
  111. Standard HRESULT code
  112. --*/
  113. {
  114. HRESULT hr = S_OK;
  115. DBG_ENTER (_T("CFaxDocument::FinalConstruct"), hr);
  116. //
  117. // Initialize instance vars
  118. //
  119. m_CallHandle = 0;
  120. m_ScheduleTime = 0;
  121. m_Priority = fptNORMAL;
  122. m_ReceiptType = frtNONE;
  123. m_ScheduleType = fstNOW;
  124. m_CoverPageType = fcptNONE;
  125. m_bAttachFax = VARIANT_FALSE;
  126. m_bUseGrouping = VARIANT_FALSE;
  127. return hr;
  128. }
  129. //
  130. //==================== CONNECTED SUBMIT =======================================
  131. //
  132. STDMETHODIMP
  133. CFaxDocument::ConnectedSubmit(
  134. /*[in]*/ IFaxServer *pFaxServer,
  135. /*[out, retval]*/ VARIANT *pvFaxOutgoingJobIDs
  136. )
  137. /*++
  138. Routine name : CFaxDocument::ConnectedSubmit
  139. Routine description:
  140. Submit the Fax Document on already connected Fax Server
  141. Author:
  142. Iv Garber (IvG), Apr, 2000
  143. Arguments:
  144. pFaxServer [in] - Fax Server to Send the Document through
  145. ppsfbstrFaxOutgoingJobIDs [out, retval] - Result : List of Created Jobs for the Document
  146. Return Value:
  147. Standard HRESULT code
  148. --*/
  149. {
  150. HRESULT hr = S_OK;
  151. bool bRes = TRUE;
  152. HANDLE hFaxHandle = NULL;
  153. LPCTSTR lpctstrFileName = NULL;
  154. DWORD dwNumRecipients = 0;
  155. long lNum = 0L;
  156. LONG_PTR i = 0;
  157. DWORDLONG dwlMessageId = 0;
  158. PDWORDLONG lpdwlRecipientMsgIds = NULL;
  159. PFAX_PERSONAL_PROFILE pRecipientsPersonalProfile = NULL;
  160. FAX_PERSONAL_PROFILE SenderPersonalProfile;
  161. PFAX_COVERPAGE_INFO_EX pCoverPageInfoEx = NULL;
  162. FAX_JOB_PARAM_EX JobParamEx;
  163. SAFEARRAY *psa = NULL;
  164. DBG_ENTER (_T("CFaxDocument::ConnectedSubmit"), hr);
  165. if (!pFaxServer)
  166. {
  167. //
  168. // Bad Return OR Interface Pointer
  169. //
  170. hr = E_POINTER;
  171. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  172. CALL_FAIL(GENERAL_ERR, _T("!pFaxServer"), hr);
  173. return hr;
  174. }
  175. if ( ::IsBadWritePtr(pvFaxOutgoingJobIDs, sizeof(VARIANT)) )
  176. {
  177. //
  178. // Bad Return OR Interface Pointer
  179. //
  180. hr = E_POINTER;
  181. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  182. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(pvFaxOutgoingJobIDs, sizeof(VARIANT))"), hr);
  183. return hr;
  184. }
  185. //
  186. // Recipients Collection must exist and must contain at least one item
  187. //
  188. if (!m_Recipients)
  189. {
  190. hr = E_INVALIDARG;
  191. Error(IDS_ERROR_NO_RECIPIENTS, IID_IFaxDocument, hr);
  192. CALL_FAIL(GENERAL_ERR, _T("!m_Recipients"), hr);
  193. return hr;
  194. }
  195. //
  196. // Get Fax Server Handle
  197. //
  198. CComQIPtr<IFaxServerInner> pIFaxServerInner(pFaxServer);
  199. if (!pIFaxServerInner)
  200. {
  201. hr = E_FAIL;
  202. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  203. CALL_FAIL(GENERAL_ERR,
  204. _T("CComQIPtr<IFaxServerInner> pIFaxServerInner(pFaxServer)"),
  205. hr);
  206. return hr;
  207. }
  208. hr = pIFaxServerInner->GetHandle(&hFaxHandle);
  209. if (FAILED(hr))
  210. {
  211. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  212. CALL_FAIL(GENERAL_ERR, _T("pIFaxServerInner->GetHandle(&hFaxHandle)"), hr);
  213. return hr;
  214. }
  215. if (hFaxHandle == NULL)
  216. {
  217. //
  218. // Fax Server is not connected
  219. //
  220. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  221. Error(IDS_ERROR_SERVER_NOT_CONNECTED, IID_IFaxDocument, hr);
  222. CALL_FAIL(GENERAL_ERR, _T("hFaxHandle==NULL"), hr);
  223. return hr;
  224. }
  225. //
  226. // Get File Name of the Document
  227. //
  228. if (m_bstrBody && (m_bstrBody.Length() > 0))
  229. {
  230. lpctstrFileName = m_bstrBody;
  231. }
  232. else
  233. {
  234. //
  235. // check that Cover Page exists
  236. //
  237. if (m_CoverPageType == fcptNONE)
  238. {
  239. //
  240. // invalid arguments combination
  241. //
  242. hr = E_INVALIDARG;
  243. Error(IDS_ERROR_NOTHING_TO_SUBMIT, IID_IFaxDocument, hr);
  244. CALL_FAIL(GENERAL_ERR, _T("No Document Body and CoverPageType == fcptNONE"), hr);
  245. return hr;
  246. }
  247. }
  248. //
  249. // Check consistency of Cover Page data
  250. //
  251. if ( (m_CoverPageType != fcptNONE) && (m_bstrCoverPage.Length() < 1))
  252. {
  253. //
  254. // Cover Page File Name is missing
  255. //
  256. hr = E_INVALIDARG;
  257. Error(IDS_ERROR_NOCOVERPAGE, IID_IFaxDocument, hr);
  258. CALL_FAIL(GENERAL_ERR, _T("CoverPageType != fcptNONE but m_bstrCoverPage is empty."), hr);
  259. return hr;
  260. }
  261. //
  262. // Prepare Cover Page data
  263. //
  264. if ((m_CoverPageType != fcptNONE) || (m_bstrSubject.Length() > 0))
  265. {
  266. pCoverPageInfoEx = PFAX_COVERPAGE_INFO_EX(MemAlloc(sizeof(FAX_COVERPAGE_INFO_EX)));
  267. if (!pCoverPageInfoEx)
  268. {
  269. //
  270. // Not enough memory
  271. //
  272. hr = E_OUTOFMEMORY;
  273. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  274. CALL_FAIL(MEM_ERR, _T("MemAlloc(sizeof(FAX_COVERPAGE_INFO_EX)"), hr);
  275. return hr;
  276. }
  277. ZeroMemory(pCoverPageInfoEx, sizeof(FAX_COVERPAGE_INFO_EX));
  278. pCoverPageInfoEx ->dwSizeOfStruct = sizeof(FAX_COVERPAGE_INFO_EX);
  279. pCoverPageInfoEx ->lptstrSubject = m_bstrSubject;
  280. if (m_CoverPageType != fcptNONE)
  281. {
  282. pCoverPageInfoEx ->dwCoverPageFormat = FAX_COVERPAGE_FMT_COV;
  283. pCoverPageInfoEx ->lptstrCoverPageFileName = m_bstrCoverPage;
  284. pCoverPageInfoEx ->bServerBased = (m_CoverPageType == fcptSERVER);
  285. pCoverPageInfoEx ->lptstrNote = m_bstrNote;
  286. }
  287. else
  288. {
  289. //
  290. // No Cover Page, only Subject
  291. //
  292. pCoverPageInfoEx ->dwCoverPageFormat = FAX_COVERPAGE_FMT_COV_SUBJECT_ONLY;
  293. }
  294. }
  295. //
  296. // Call Sender Profile to Bring its Data
  297. //
  298. hr = m_Sender.GetSenderProfile(&SenderPersonalProfile);
  299. if (FAILED(hr))
  300. {
  301. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  302. CALL_FAIL(GENERAL_ERR, _T("m_Sender.GetSenderProfile(&SenderPersonalProfile)"), hr);
  303. goto error;
  304. }
  305. //
  306. // Get Number of Recipients
  307. //
  308. hr = m_Recipients->get_Count(&lNum);
  309. if (FAILED(hr))
  310. {
  311. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  312. CALL_FAIL(GENERAL_ERR, _T("m_Recipients->get_Count()"), hr);
  313. goto error;
  314. }
  315. if (lNum <= 0)
  316. {
  317. hr = E_INVALIDARG;
  318. Error(IDS_ERROR_NO_RECIPIENTS, IID_IFaxDocument, hr);
  319. CALL_FAIL(GENERAL_ERR, _T("!m_Recipients"), hr);
  320. goto error;
  321. }
  322. //
  323. // TapiConnection / CallHandle support
  324. //
  325. if (m_TapiConnection || (m_CallHandle != 0))
  326. {
  327. if (lNum > 1)
  328. {
  329. //
  330. // ONLY ONE Recipient is allowed in this case
  331. //
  332. hr = E_INVALIDARG;
  333. Error(IDS_ERROR_ILLEGAL_RECIPIENTS, IID_IFaxDocument, hr);
  334. CALL_FAIL(GENERAL_ERR, _T("TapiConnection and/or CallHandle + more than ONE Recipients."), hr);
  335. goto error;
  336. }
  337. if (m_TapiConnection)
  338. {
  339. //
  340. // Pass TapiConnection to the Fax Service
  341. //
  342. JobParamEx.dwReserved[0] = 0xFFFF1234;
  343. JobParamEx.dwReserved[1] = DWORD_PTR(m_TapiConnection.p);
  344. }
  345. }
  346. //
  347. // Total number of Recipients
  348. //
  349. dwNumRecipients = lNum;
  350. //
  351. // Get Array of Recipient Personal Profiles
  352. //
  353. pRecipientsPersonalProfile = PFAX_PERSONAL_PROFILE(MemAlloc(sizeof(FAX_PERSONAL_PROFILE) * lNum));
  354. if (!pRecipientsPersonalProfile)
  355. {
  356. //
  357. // Not enough memory
  358. //
  359. hr = E_OUTOFMEMORY;
  360. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  361. CALL_FAIL(MEM_ERR, _T("MemAlloc(sizeof(FAX_PERSONAL_PROFILE) * lNum)"), hr);
  362. goto error;
  363. }
  364. for ( i = 1 ; i <= lNum ; i++ )
  365. {
  366. //
  367. // Get Next Recipient
  368. //
  369. CComPtr<IFaxRecipient> pCurrRecipient = NULL;
  370. hr = m_Recipients->get_Item(i, &pCurrRecipient);
  371. if (FAILED(hr))
  372. {
  373. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  374. CALL_FAIL(GENERAL_ERR, _T("m_Recipients->get_Item(i, &pCurrRecipient)"), hr);
  375. goto error;
  376. }
  377. //
  378. // Get its Data
  379. //
  380. BSTR bstrName = NULL;
  381. BSTR bstrFaxNumber = NULL;
  382. hr = pCurrRecipient->get_Name(&bstrName);
  383. if (FAILED(hr))
  384. {
  385. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  386. CALL_FAIL(GENERAL_ERR, _T("pCurrRecipient->get_Name(&bstrName)"), hr);
  387. goto error;
  388. }
  389. hr = pCurrRecipient->get_FaxNumber(&bstrFaxNumber);
  390. if (FAILED(hr))
  391. {
  392. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  393. CALL_FAIL(GENERAL_ERR, _T("pCurrRecipient->get_FaxNumber(&bstrFaxNumber)"), hr);
  394. goto error;
  395. }
  396. //
  397. // Store the data to pass at Fax Submit
  398. //
  399. FAX_PERSONAL_PROFILE currProfile = {0};
  400. currProfile.dwSizeOfStruct = sizeof(FAX_PERSONAL_PROFILE);
  401. currProfile.lptstrFaxNumber = bstrFaxNumber;
  402. currProfile.lptstrName = bstrName;
  403. *(pRecipientsPersonalProfile + i - 1) = currProfile;
  404. }
  405. //
  406. // Fill Job Params
  407. //
  408. JobParamEx.dwSizeOfStruct = sizeof(FAX_JOB_PARAM_EX);
  409. JobParamEx.lptstrReceiptDeliveryAddress = m_bstrReceiptAddress;
  410. JobParamEx.Priority = FAX_ENUM_PRIORITY_TYPE(m_Priority);
  411. JobParamEx.lptstrDocumentName = m_bstrDocName;
  412. JobParamEx.dwScheduleAction = m_ScheduleType;
  413. JobParamEx.dwPageCount = 0;
  414. JobParamEx.hCall = m_CallHandle; // either Zero or Valid Value
  415. if ((m_bUseGrouping == VARIANT_TRUE) && (dwNumRecipients > 1))
  416. {
  417. JobParamEx.dwReceiptDeliveryType = m_ReceiptType | DRT_GRP_PARENT;
  418. }
  419. else
  420. {
  421. JobParamEx.dwReceiptDeliveryType = m_ReceiptType;
  422. }
  423. //
  424. // Add AttachFaxToReceipt flag if applicable.
  425. //
  426. // The conditions are :
  427. // 1. m_bAttachFax is set to VARIANT_TRUE
  428. // 2. ReceiptType is MAIL
  429. // 3. The next case is NOT the current one :
  430. // m_bUseGrouping is set to VARIANT_TRUE
  431. // no Body
  432. // Number of Recipients is more than ONE
  433. //
  434. if ( (m_bAttachFax == VARIANT_TRUE)
  435. &&
  436. (m_ReceiptType == frtMAIL)
  437. &&
  438. ((m_bUseGrouping == VARIANT_FALSE) || (m_bstrBody) || (dwNumRecipients == 1))
  439. )
  440. {
  441. JobParamEx.dwReceiptDeliveryType |= DRT_ATTACH_FAX;
  442. }
  443. if (m_ScheduleType == fstSPECIFIC_TIME)
  444. {
  445. if (m_ScheduleTime == 0)
  446. {
  447. //
  448. // Invalid Combination
  449. //
  450. hr = E_INVALIDARG;
  451. Error(IDS_ERROR_SCHEDULE_TYPE, IID_IFaxDocument, hr);
  452. CALL_FAIL(GENERAL_ERR,
  453. _T("m_ScheduleType==fstSPECIFIC_TIME but m_ScheduleTime==0"),
  454. hr);
  455. goto error;
  456. }
  457. SYSTEMTIME ScheduleTime;
  458. if (TRUE != VariantTimeToSystemTime(m_ScheduleTime, &ScheduleTime))
  459. {
  460. //
  461. // VariantTimeToSystemTime failed
  462. //
  463. hr = E_INVALIDARG;
  464. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  465. CALL_FAIL(GENERAL_ERR, _T("VariantTimeToSystemTime"), hr);
  466. goto error;
  467. }
  468. JobParamEx.tmSchedule = ScheduleTime;
  469. }
  470. lpdwlRecipientMsgIds = PDWORDLONG(MemAlloc(sizeof(DWORDLONG) * lNum));
  471. if (!lpdwlRecipientMsgIds)
  472. {
  473. //
  474. // Not enough memory
  475. //
  476. hr = E_OUTOFMEMORY;
  477. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  478. CALL_FAIL(MEM_ERR, _T("MemAlloc(sizeof(DWORDLONG) * lNum"), hr);
  479. goto error;
  480. }
  481. if ( FALSE == FaxSendDocumentEx(hFaxHandle,
  482. lpctstrFileName,
  483. pCoverPageInfoEx,
  484. &SenderPersonalProfile,
  485. dwNumRecipients,
  486. pRecipientsPersonalProfile,
  487. &JobParamEx,
  488. &dwlMessageId,
  489. lpdwlRecipientMsgIds) )
  490. {
  491. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  492. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  493. CALL_FAIL(GENERAL_ERR, _T("FaxSendDocumentEx()"), hr);
  494. goto error;
  495. }
  496. //
  497. // Put Received Job Ids into SafeArray
  498. //
  499. psa = ::SafeArrayCreateVector(VT_BSTR, 0, lNum);
  500. if (!psa)
  501. {
  502. //
  503. // Not Enough Memory
  504. //
  505. hr = E_OUTOFMEMORY;
  506. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  507. CALL_FAIL(MEM_ERR, _T("::SafeArrayCreate()"), hr);
  508. goto error;
  509. }
  510. BSTR *pbstr;
  511. hr = ::SafeArrayAccessData(psa, (void **) &pbstr);
  512. if (FAILED(hr))
  513. {
  514. //
  515. // Failed to access safearray
  516. //
  517. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  518. CALL_FAIL(GENERAL_ERR, _T("::SafeArrayAccessData()"), hr);
  519. goto error;
  520. }
  521. TCHAR tcBuffer[25];
  522. for ( i = 0 ; i < lNum ; i++ )
  523. {
  524. ::_i64tot(lpdwlRecipientMsgIds[i], tcBuffer, 16);
  525. pbstr[i] = ::SysAllocString(tcBuffer);
  526. if (pbstr[i] == NULL)
  527. {
  528. //
  529. // Not Enough Memory
  530. //
  531. hr = E_OUTOFMEMORY;
  532. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  533. CALL_FAIL(MEM_ERR, _T("::SysAllocString()"), hr);
  534. goto error;
  535. }
  536. }
  537. hr = SafeArrayUnaccessData(psa);
  538. if (FAILED(hr))
  539. {
  540. CALL_FAIL(GENERAL_ERR, _T("::SafeArrayUnaccessData(psa)"), hr);
  541. }
  542. VariantInit(pvFaxOutgoingJobIDs);
  543. pvFaxOutgoingJobIDs->vt = VT_BSTR | VT_ARRAY;
  544. pvFaxOutgoingJobIDs->parray = psa;
  545. goto ok;
  546. error:
  547. //
  548. // Delete SafeArray only in the case on an Error
  549. //
  550. if (psa)
  551. {
  552. SafeArrayDestroy(psa);
  553. }
  554. ok:
  555. if (pCoverPageInfoEx)
  556. {
  557. MemFree(pCoverPageInfoEx);
  558. }
  559. if (pRecipientsPersonalProfile)
  560. {
  561. for (i = 0 ; i < dwNumRecipients ; i++ )
  562. {
  563. //
  564. // Free the Name and the Fax Number of each Recipient.
  565. //
  566. // Notice these are BSTRs (although in the FAX_PERSONAL_PROFILE structure
  567. // they are treated as LPCTSTRs) since we get them by calling
  568. // pCurrRecipient->get_Name() and pCurrRecipient->get_FaxNumber().
  569. //
  570. BSTR bstrName = (BSTR)(pRecipientsPersonalProfile[i].lptstrName);
  571. BSTR bstrFaxNumber = (BSTR)(pRecipientsPersonalProfile[i].lptstrFaxNumber);
  572. ::SysFreeString(bstrName);
  573. ::SysFreeString(bstrFaxNumber);
  574. }
  575. MemFree(pRecipientsPersonalProfile);
  576. }
  577. if (lpdwlRecipientMsgIds)
  578. {
  579. MemFree(lpdwlRecipientMsgIds);
  580. }
  581. return hr;
  582. }
  583. //
  584. //==================== INTERFACE SUPPORT ERROR INFO =======================
  585. //
  586. STDMETHODIMP
  587. CFaxDocument::InterfaceSupportsErrorInfo (
  588. REFIID riid
  589. )
  590. /*++
  591. Routine name : CFaxRecipients::InterfaceSupportsErrorInfo
  592. Routine description:
  593. ATL's implementation of Support Error Info
  594. Author:
  595. Iv Garber (IvG), Apr, 2000
  596. Arguments:
  597. riid [in] - Interface ID
  598. Return Value:
  599. Standard HRESULT code
  600. --*/
  601. {
  602. static const IID* arr[] =
  603. {
  604. &IID_IFaxDocument
  605. };
  606. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  607. {
  608. if (InlineIsEqualGUID(*arr[i],riid))
  609. return S_OK;
  610. }
  611. return S_FALSE;
  612. }
  613. //
  614. //========================= GET OBJECTS ======================================
  615. //
  616. STDMETHODIMP
  617. CFaxDocument::get_Sender (
  618. IFaxSender **ppFaxSender
  619. )
  620. /*++
  621. Routine name : CFaxDocument::get_Sender
  622. Routine description:
  623. Return Default Sender Information
  624. Author:
  625. Iv Garber (IvG), Apr, 2000
  626. Arguments:
  627. ppFaxSender [out] - current Sender object
  628. Return Value:
  629. Standard HRESULT code
  630. --*/
  631. {
  632. HRESULT hr = S_OK;
  633. DBG_ENTER (_T("CFaxDocument::get_Sender"), hr);
  634. if (::IsBadWritePtr(ppFaxSender, sizeof(IFaxSender *)))
  635. {
  636. //
  637. // Got a bad return pointer
  638. //
  639. hr = E_POINTER;
  640. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  641. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  642. return hr;
  643. }
  644. //
  645. // Sender Profile is created at Final Construct
  646. //
  647. hr = m_Sender.QueryInterface(ppFaxSender);
  648. if (FAILED(hr))
  649. {
  650. //
  651. // Failed to copy interface
  652. //
  653. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  654. CALL_FAIL(GENERAL_ERR, _T("CCom<IFaxSender>::CopyTo()"), hr);
  655. return hr;
  656. }
  657. return hr;
  658. }
  659. STDMETHODIMP
  660. CFaxDocument::get_Recipients (
  661. IFaxRecipients **ppFaxRecipients
  662. )
  663. /*++
  664. Routine name : CFaxDocument::get_Recipients
  665. Routine description:
  666. Return Recipients Collection
  667. Author:
  668. Iv Garber (IvG), Apr, 2000
  669. Arguments:
  670. ppFaxRecipients [out] - The Recipients Collection
  671. Return Value:
  672. Standard HRESULT code
  673. --*/
  674. {
  675. HRESULT hr = S_OK;
  676. DBG_ENTER (_T("CFaxDocument::get_Recipients"), hr);
  677. if (::IsBadWritePtr(ppFaxRecipients, sizeof(IFaxRecipients *)))
  678. {
  679. //
  680. // Got a bad return pointer
  681. //
  682. hr = E_POINTER;
  683. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  684. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  685. return hr;
  686. }
  687. if (!(m_Recipients))
  688. {
  689. //
  690. // Create collection on demand only once.
  691. //
  692. hr = CFaxRecipients::Create(&m_Recipients);
  693. if (FAILED(hr))
  694. {
  695. //
  696. // Failure to create recipients collection
  697. //
  698. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  699. CALL_FAIL(GENERAL_ERR, _T("CFaxRecipients::Create"), hr);
  700. return hr;
  701. }
  702. }
  703. hr = m_Recipients.CopyTo(ppFaxRecipients);
  704. if (FAILED(hr))
  705. {
  706. //
  707. // Failed to copy Interface
  708. //
  709. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  710. CALL_FAIL(GENERAL_ERR, _T("CComBSTR::CopyTo"), hr);
  711. return hr;
  712. }
  713. return hr;
  714. }
  715. //
  716. //========================= PUT BSTR ATTRIBUTES ========================
  717. //
  718. STDMETHODIMP
  719. CFaxDocument::put_Body (
  720. BSTR bstrBody
  721. )
  722. /*++
  723. Routine name : CFaxDocument::put_Body
  724. Routine description:
  725. Set Body of the Document. Receives full path to the file to send through fax server.
  726. Author:
  727. Iv Garber (IvG), May, 2001
  728. Arguments:
  729. bstrBody [in] - the Body of the Document.
  730. Return Value:
  731. Standard HRESULT code
  732. --*/
  733. {
  734. HRESULT hr = S_OK;
  735. DBG_ENTER (_T("CFaxDocument::put_Body"), hr, _T("%s"), bstrBody);
  736. m_bstrBody = bstrBody;
  737. if (bstrBody && !m_bstrBody)
  738. {
  739. //
  740. // not enough memory
  741. //
  742. hr = E_OUTOFMEMORY;
  743. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  744. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  745. return hr;
  746. }
  747. return hr;
  748. }
  749. STDMETHODIMP
  750. CFaxDocument::put_CoverPage (
  751. BSTR bstrCoverPage
  752. )
  753. /*++
  754. Routine name : CFaxDocument::put_CoverPage
  755. Routine description:
  756. Set Cover Page
  757. Author:
  758. Iv Garber (IvG), Apr, 2000
  759. Arguments:
  760. bstrCoverPage [in] - new Cover Page value
  761. Return Value:
  762. Standard HRESULT code
  763. --*/
  764. {
  765. HRESULT hr = S_OK;
  766. DBG_ENTER (_T("CFaxDocument::put_CoverPage"), hr, _T("%s"), bstrCoverPage);
  767. m_bstrCoverPage = bstrCoverPage;
  768. if (bstrCoverPage && !m_bstrCoverPage)
  769. {
  770. //
  771. // not enough memory
  772. //
  773. hr = E_OUTOFMEMORY;
  774. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  775. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  776. return hr;
  777. }
  778. return hr;
  779. }
  780. STDMETHODIMP
  781. CFaxDocument::put_Subject (
  782. BSTR bstrSubject
  783. )
  784. /*++
  785. Routine name : CFaxDocument::put_Subject
  786. Routine description:
  787. Set Subject of the Fax Document
  788. Author:
  789. Iv Garber (IvG), Apr, 2000
  790. Arguments:
  791. bstrSubject [in] - The new Subject value
  792. Return Value:
  793. Standard HRESULT code
  794. --*/
  795. {
  796. HRESULT hr = S_OK;
  797. DBG_ENTER (_T("CFaxDocument::put_Subject"), hr, _T("%s"), bstrSubject);
  798. m_bstrSubject = bstrSubject;
  799. if (bstrSubject && !m_bstrSubject)
  800. {
  801. //
  802. // not enough memory
  803. //
  804. hr = E_OUTOFMEMORY;
  805. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  806. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  807. return hr;
  808. }
  809. return hr;
  810. }
  811. STDMETHODIMP
  812. CFaxDocument::put_Note (
  813. BSTR bstrNote
  814. )
  815. /*++
  816. Routine name : CFaxDocument::put_Note
  817. Routine description:
  818. Set Note for the Document
  819. Author:
  820. Iv Garber (IvG), Apr, 2000
  821. Arguments:
  822. bstrNote [in] - the new Note field
  823. Return Value:
  824. Standard HRESULT code
  825. --*/
  826. {
  827. HRESULT hr = S_OK;
  828. DBG_ENTER (_T("CFaxDocument::put_Note"), hr, _T("%s"), bstrNote);
  829. m_bstrNote = bstrNote;
  830. if (bstrNote && !m_bstrNote)
  831. {
  832. //
  833. // not enough memory
  834. //
  835. hr = E_OUTOFMEMORY;
  836. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  837. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  838. return hr;
  839. }
  840. return hr;
  841. }
  842. STDMETHODIMP
  843. CFaxDocument::put_DocumentName (
  844. BSTR bstrDocumentName
  845. )
  846. /*++
  847. Routine name : CFaxDocument::put_DocumentName
  848. Routine description:
  849. Set the Name of the Document
  850. Author:
  851. Iv Garber (IvG), Apr, 2000
  852. Arguments:
  853. bstrDocumentName [in] - the new Name of the Document
  854. Return Value:
  855. Standard HRESULT code
  856. --*/
  857. {
  858. HRESULT hr = S_OK;
  859. DBG_ENTER (_T("CFaxDocument::put_DocumentName"),
  860. hr,
  861. _T("%s"),
  862. bstrDocumentName);
  863. m_bstrDocName = bstrDocumentName;
  864. if (bstrDocumentName && !m_bstrDocName)
  865. {
  866. //
  867. // not enough memory
  868. //
  869. hr = E_OUTOFMEMORY;
  870. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  871. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  872. return hr;
  873. }
  874. return hr;
  875. }
  876. STDMETHODIMP
  877. CFaxDocument::put_ReceiptAddress (
  878. BSTR bstrReceiptAddress
  879. )
  880. /*++
  881. Routine name : CFaxDocument::put_ReceiptAddress
  882. Routine description:
  883. Set Receipt Address
  884. Author:
  885. Iv Garber (IvG), Apr, 2000
  886. Arguments:
  887. bstrReceiptAddress [in] - the Receipt Address
  888. Return Value:
  889. Standard HRESULT code
  890. --*/
  891. {
  892. HRESULT hr = S_OK;
  893. DBG_ENTER (_T("CFaxDocument::put_ReceiptAddress"),
  894. hr,
  895. _T("%s"),
  896. bstrReceiptAddress);
  897. m_bstrReceiptAddress = bstrReceiptAddress;
  898. if (bstrReceiptAddress && !m_bstrReceiptAddress)
  899. {
  900. //
  901. // not enough memory
  902. //
  903. hr = E_OUTOFMEMORY;
  904. Error(IDS_ERROR_OUTOFMEMORY, IID_IFaxDocument, hr);
  905. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  906. return hr;
  907. }
  908. return hr;
  909. }
  910. //
  911. //========================= GET BSTR ATTRIBUTES ========================
  912. //
  913. STDMETHODIMP
  914. CFaxDocument::get_Body (
  915. BSTR *pbstrBody
  916. )
  917. /*++
  918. Routine name : CFaxDocument::get_Body
  919. Routine description:
  920. Returns full path to the file containing the Body of the Document to send.
  921. Author:
  922. Iv Garber (IvG), May, 2001
  923. Arguments:
  924. pbstrBody [out] - ptr to place to put the Body path
  925. Return Value:
  926. Standard HRESULT code
  927. --*/
  928. {
  929. HRESULT hr = S_OK;
  930. DBG_ENTER (TEXT("CFaxDocument::get_Body"), hr);
  931. hr = GetBstr(pbstrBody, m_bstrBody);
  932. if (FAILED(hr))
  933. {
  934. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  935. return hr;
  936. }
  937. return hr;
  938. }
  939. STDMETHODIMP
  940. CFaxDocument::get_CoverPage (
  941. BSTR *pbstrCoverPage
  942. )
  943. /*++
  944. Routine name : CFaxDocument::get_CoverPage
  945. Routine description:
  946. Return Cover Page Path
  947. Author:
  948. Iv Garber (IvG), Apr, 2000
  949. Arguments:
  950. pbstrCoverPage [out] - ptr to place to put the Cover Page Path
  951. Return Value:
  952. Standard HRESULT code
  953. --*/
  954. {
  955. HRESULT hr = S_OK;
  956. DBG_ENTER (TEXT("CFaxDocument::get_CoverPage"), hr);
  957. hr = GetBstr(pbstrCoverPage, m_bstrCoverPage);
  958. if (FAILED(hr))
  959. {
  960. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  961. return hr;
  962. }
  963. return hr;
  964. }
  965. STDMETHODIMP
  966. CFaxDocument::get_Subject (
  967. BSTR *pbstrSubject
  968. )
  969. /*++
  970. Routine name : CFaxDocument::get_Subject
  971. Routine description:
  972. Return Subject
  973. Author:
  974. Iv Garber (IvG), Apr, 2000
  975. Arguments:
  976. pbstrSubject [out] - The Document's Subject
  977. Return Value:
  978. Standard HRESULT code
  979. --*/
  980. {
  981. HRESULT hr = S_OK;
  982. DBG_ENTER (TEXT("CFaxDocument::get_Subject"), hr);
  983. hr = GetBstr(pbstrSubject, m_bstrSubject);
  984. if (FAILED(hr))
  985. {
  986. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  987. return hr;
  988. }
  989. return hr;
  990. }
  991. STDMETHODIMP
  992. CFaxDocument::get_Note(
  993. BSTR *pbstrNote
  994. )
  995. /*++
  996. Routine name : CFaxDocument::get_Note
  997. Routine description:
  998. Return Note field of the Cover Page
  999. Author:
  1000. Iv Garber (IvG), Apr, 2000
  1001. Arguments:
  1002. pbstrNote [out] - the Note
  1003. Return Value:
  1004. Standard HRESULT code
  1005. --*/
  1006. {
  1007. HRESULT hr = S_OK;
  1008. DBG_ENTER (TEXT("CFaxDocument::get_Note"), hr);
  1009. hr = GetBstr(pbstrNote, m_bstrNote);
  1010. if (FAILED(hr))
  1011. {
  1012. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  1013. return hr;
  1014. }
  1015. return hr;
  1016. }
  1017. STDMETHODIMP
  1018. CFaxDocument::get_DocumentName(
  1019. BSTR *pbstrDocumentName
  1020. )
  1021. /*++
  1022. Routine name : CFaxDocument::get_DocumentName
  1023. Routine description:
  1024. Return Document Name
  1025. Author:
  1026. Iv Garber (IvG), Apr, 2000
  1027. Arguments:
  1028. pbstrDocumentName [out] - Name of the Document
  1029. Return Value:
  1030. Standard HRESULT code
  1031. --*/
  1032. {
  1033. HRESULT hr = S_OK;
  1034. DBG_ENTER (TEXT("CFaxDocument::get_Document Name"), hr);
  1035. hr = GetBstr(pbstrDocumentName, m_bstrDocName);
  1036. if (FAILED(hr))
  1037. {
  1038. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  1039. return hr;
  1040. }
  1041. return hr;
  1042. }
  1043. STDMETHODIMP
  1044. CFaxDocument::get_ReceiptAddress(
  1045. BSTR *pbstrReceiptAddress
  1046. )
  1047. /*++
  1048. Routine name : CFaxDocument::get_ReceiptAddress
  1049. Routine description:
  1050. Return Receipt Address
  1051. Author:
  1052. Iv Garber (IvG), Apr, 2000
  1053. Arguments:
  1054. pbstrReceiptAddress [out] - Receipt Address
  1055. Return Value:
  1056. Standard HRESULT code
  1057. --*/
  1058. {
  1059. HRESULT hr = S_OK;
  1060. DBG_ENTER (TEXT("CFaxDocument::get_ReceiptAddress"), hr);
  1061. hr = GetBstr(pbstrReceiptAddress, m_bstrReceiptAddress);
  1062. if (FAILED(hr))
  1063. {
  1064. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  1065. return hr;
  1066. }
  1067. return hr;
  1068. }
  1069. //
  1070. //========================= GET & PUT OTHER ATTRIBUTES ========================
  1071. //
  1072. STDMETHODIMP
  1073. CFaxDocument::get_ScheduleTime(
  1074. DATE *pdateScheduleTime
  1075. )
  1076. /*++
  1077. Routine name : CFaxDocument::get_ScheduleTime
  1078. Routine description:
  1079. Return Schedule Time
  1080. Author:
  1081. Iv Garber (IvG), Apr, 2000
  1082. Arguments:
  1083. pdateScheduleTime [out] - the Schedule Time
  1084. Return Value:
  1085. Standard HRESULT code
  1086. --*/
  1087. {
  1088. HRESULT hr = S_OK;
  1089. DBG_ENTER (TEXT("CFaxDocument::get_ScheduleTime"), hr);
  1090. //
  1091. // Check that we can write to the given pointer
  1092. //
  1093. if (::IsBadWritePtr(pdateScheduleTime, sizeof(DATE)))
  1094. {
  1095. //
  1096. // Got Bad Ptr
  1097. //
  1098. hr = E_POINTER;
  1099. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1100. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  1101. return hr;
  1102. }
  1103. *pdateScheduleTime = m_ScheduleTime;
  1104. return hr;
  1105. }
  1106. STDMETHODIMP
  1107. CFaxDocument::put_ScheduleTime(
  1108. DATE dateScheduleTime
  1109. )
  1110. /*++
  1111. Routine name : CFaxDocument::put_ScheduleTime
  1112. Routine description:
  1113. Return Schedule Time
  1114. Author:
  1115. Iv Garber (IvG), Apr, 2000
  1116. Arguments:
  1117. dateScheduleTime [in] - the new Schedule Time
  1118. Return Value:
  1119. Standard HRESULT code
  1120. --*/
  1121. {
  1122. HRESULT hr = S_OK;
  1123. DBG_ENTER (_T("CFaxDocument::put_ScheduleTime"),
  1124. hr,
  1125. _T("%f"),
  1126. dateScheduleTime);
  1127. m_ScheduleTime = dateScheduleTime;
  1128. return hr;
  1129. }
  1130. STDMETHODIMP
  1131. CFaxDocument::get_CallHandle(
  1132. long *plCallHandle
  1133. )
  1134. /*++
  1135. Routine name : CFaxDocument::get_CallHandle
  1136. Routine description:
  1137. Return Call Handle
  1138. Author:
  1139. Iv Garber (IvG), Apr, 2000
  1140. Arguments:
  1141. plCallHandle [out] - Call Handle
  1142. Return Value:
  1143. Standard HRESULT code
  1144. --*/
  1145. {
  1146. HRESULT hr = S_OK;
  1147. DBG_ENTER (TEXT("CFaxDocument::get_CallHandle"), hr);
  1148. hr = GetLong(plCallHandle, m_CallHandle);
  1149. if (FAILED(hr))
  1150. {
  1151. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  1152. return hr;
  1153. }
  1154. return hr;
  1155. }
  1156. STDMETHODIMP
  1157. CFaxDocument::put_CallHandle(
  1158. long lCallHandle
  1159. )
  1160. /*++
  1161. Routine name : CFaxDocument::put_CallHandle
  1162. Routine description:
  1163. Set Call Handle
  1164. Author:
  1165. Iv Garber (IvG), Apr, 2000
  1166. Arguments:
  1167. lCallHandle [in] - Call Handle to Set
  1168. Return Value:
  1169. Standard HRESULT code
  1170. --*/
  1171. {
  1172. HRESULT hr = S_OK;
  1173. DBG_ENTER (_T("CFaxDocument::put_CallHandle"), hr, _T("%ld"), lCallHandle);
  1174. m_CallHandle = lCallHandle;
  1175. return hr;
  1176. }
  1177. STDMETHODIMP
  1178. CFaxDocument::get_CoverPageType(
  1179. FAX_COVERPAGE_TYPE_ENUM *pCoverPageType
  1180. )
  1181. /*++
  1182. Routine name : CFaxDocument::get_CoverPageType
  1183. Routine description:
  1184. Returns Type of the Cover Page used : whether it is Local or Server Cover Page,
  1185. or the Cover Page is not used.
  1186. Author:
  1187. Iv Garber (IvG), Nov, 2000
  1188. Arguments:
  1189. pCoverPageType [out] - ptr to the place to put the Cover Page Type
  1190. Return Value:
  1191. Standard HRESULT code
  1192. --*/
  1193. {
  1194. HRESULT hr = S_OK;
  1195. DBG_ENTER (TEXT("CFaxDocument::get_CoverPageType"), hr);
  1196. //
  1197. // Check that we can write to the given pointer
  1198. //
  1199. if (::IsBadWritePtr(pCoverPageType, sizeof(FAX_COVERPAGE_TYPE_ENUM)))
  1200. {
  1201. //
  1202. // Got Bad Return Pointer
  1203. //
  1204. hr = E_POINTER;
  1205. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1206. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  1207. return hr;
  1208. }
  1209. *pCoverPageType = m_CoverPageType;
  1210. return hr;
  1211. }
  1212. STDMETHODIMP
  1213. CFaxDocument::put_CoverPageType(
  1214. FAX_COVERPAGE_TYPE_ENUM CoverPageType
  1215. )
  1216. /*++
  1217. Routine name : CFaxDocument::put_CoverPageType
  1218. Routine description:
  1219. Set Type of the Cover Page : either Local or Server or do not use Cover Page.
  1220. Author:
  1221. Iv Garber (IvG), Nov, 2000
  1222. Arguments:
  1223. CoverPageType [in] - the new Value of the Type
  1224. Return Value:
  1225. Standard HRESULT code
  1226. --*/
  1227. {
  1228. HRESULT hr = S_OK;
  1229. DBG_ENTER (_T("CFaxDocument::put_CoverPageType"), hr, _T("%ld"), CoverPageType);
  1230. if (CoverPageType < fcptNONE || CoverPageType > fcptSERVER)
  1231. {
  1232. //
  1233. // Cover Page Type is wrong
  1234. //
  1235. hr = E_INVALIDARG;
  1236. Error(IDS_ERROR_OUTOFRANGE, IID_IFaxDocument, hr);
  1237. CALL_FAIL(GENERAL_ERR, _T("Cover Page Type is out of range"), hr);
  1238. return hr;
  1239. }
  1240. m_CoverPageType = FAX_COVERPAGE_TYPE_ENUM(CoverPageType);
  1241. return hr;
  1242. }
  1243. STDMETHODIMP
  1244. CFaxDocument::get_ScheduleType(
  1245. FAX_SCHEDULE_TYPE_ENUM *pScheduleType
  1246. )
  1247. /*++
  1248. Routine name : CFaxDocument::get_ScheduleType
  1249. Routine description:
  1250. Return Schedule Type
  1251. Author:
  1252. Iv Garber (IvG), Apr, 2000
  1253. Arguments:
  1254. pScheduleType [out] - ptr to put the Current Schedule Type
  1255. Return Value:
  1256. Standard HRESULT code
  1257. --*/
  1258. {
  1259. HRESULT hr = S_OK;
  1260. DBG_ENTER (TEXT("CFaxDocument::get_ScheduleType"), hr);
  1261. //
  1262. // Check that we can write to the given pointer
  1263. //
  1264. if (::IsBadWritePtr(pScheduleType, sizeof(FAX_SCHEDULE_TYPE_ENUM)))
  1265. {
  1266. //
  1267. // Got Bad Return Pointer
  1268. //
  1269. hr = E_POINTER;
  1270. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1271. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  1272. return hr;
  1273. }
  1274. *pScheduleType = m_ScheduleType;
  1275. return hr;
  1276. }
  1277. STDMETHODIMP
  1278. CFaxDocument::put_ScheduleType(
  1279. FAX_SCHEDULE_TYPE_ENUM ScheduleType
  1280. )
  1281. /*++
  1282. Routine name : CFaxDocument::put_ScheduleType
  1283. Routine description:
  1284. Set Schedule Type
  1285. Author:
  1286. Iv Garber (IvG), Apr, 2000
  1287. Arguments:
  1288. ScheduleType [in] - new Schedule Type
  1289. Return Value:
  1290. Standard HRESULT code
  1291. --*/
  1292. {
  1293. HRESULT hr = S_OK;
  1294. DBG_ENTER (_T("CFaxDocument::put_ScheduleType"), hr, _T("Type=%d"), ScheduleType);
  1295. if (ScheduleType < fstNOW || ScheduleType > fstDISCOUNT_PERIOD)
  1296. {
  1297. //
  1298. // Schedule Type is wrong
  1299. //
  1300. hr = E_INVALIDARG;
  1301. Error(IDS_ERROR_OUTOFRANGE, IID_IFaxDocument, hr);
  1302. CALL_FAIL(GENERAL_ERR, _T("Schedule Type is out of range"), hr);
  1303. return hr;
  1304. }
  1305. m_ScheduleType = FAX_SCHEDULE_TYPE_ENUM(ScheduleType);
  1306. return hr;
  1307. }
  1308. STDMETHODIMP
  1309. CFaxDocument::get_ReceiptType(
  1310. FAX_RECEIPT_TYPE_ENUM *pReceiptType
  1311. )
  1312. /*++
  1313. Routine name : CFaxDocument::get_ReceiptType
  1314. Routine description:
  1315. Return Receipt Type
  1316. Author:
  1317. Iv Garber (IvG), Apr, 2000
  1318. Arguments:
  1319. pReceiptType [out] - ptr to put the Current Receipt Type
  1320. Return Value:
  1321. Standard HRESULT code
  1322. --*/
  1323. {
  1324. HRESULT hr = S_OK;
  1325. DBG_ENTER (TEXT("CFaxDocument::get_ReceiptType"), hr);
  1326. //
  1327. // Check that we can write to the given pointer
  1328. //
  1329. if (::IsBadWritePtr(pReceiptType, sizeof(FAX_SCHEDULE_TYPE_ENUM)))
  1330. {
  1331. //
  1332. // Got Bad Return Pointer
  1333. //
  1334. hr = E_POINTER;
  1335. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1336. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  1337. return hr;
  1338. }
  1339. *pReceiptType = m_ReceiptType;
  1340. return hr;
  1341. }
  1342. STDMETHODIMP
  1343. CFaxDocument::put_ReceiptType(
  1344. FAX_RECEIPT_TYPE_ENUM ReceiptType
  1345. )
  1346. /*++
  1347. Routine name : CFaxDocument::put_ReceiptType
  1348. Routine description:
  1349. Set Receipt Type
  1350. Author:
  1351. Iv Garber (IvG), Apr, 2000
  1352. Arguments:
  1353. ReceiptType [in] - new Receipt Type
  1354. Return Value:
  1355. Standard HRESULT code
  1356. --*/
  1357. {
  1358. HRESULT hr = S_OK;
  1359. DBG_ENTER (_T("CFaxDocument::put_ReceiptType"), hr, _T("%d"), ReceiptType);
  1360. if ((ReceiptType != frtNONE) && (ReceiptType != frtMSGBOX) && (ReceiptType != frtMAIL))
  1361. {
  1362. //
  1363. // Out of range
  1364. //
  1365. hr = E_INVALIDARG;
  1366. Error(IDS_ERROR_OUTOFRANGE, IID_IFaxDocument, hr);
  1367. CALL_FAIL(GENERAL_ERR, _T("Receipt Type is out of range. It may be one of the values allowed by the Server."), hr);
  1368. return hr;
  1369. }
  1370. m_ReceiptType = FAX_RECEIPT_TYPE_ENUM(ReceiptType);
  1371. return hr;
  1372. }
  1373. STDMETHODIMP
  1374. CFaxDocument::get_AttachFaxToReceipt(
  1375. VARIANT_BOOL *pbAttachFax
  1376. )
  1377. /*++
  1378. Routine name : CFaxDocument::get_AttachFaxToReceipt
  1379. Routine description:
  1380. Return Flag indicating whether or not Fax Service should Attach Fax To the Receipt
  1381. Author:
  1382. Iv Garber (IvG), Dec, 2000
  1383. Arguments:
  1384. pbAttachFax [out] - the Current value of the Flag
  1385. Return Value:
  1386. Standard HRESULT code
  1387. --*/
  1388. {
  1389. HRESULT hr = S_OK;
  1390. DBG_ENTER (_T("CFaxDocument::get_AttachFaxToReceipt"), hr);
  1391. hr = GetVariantBool(pbAttachFax, m_bAttachFax);
  1392. if (FAILED(hr))
  1393. {
  1394. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  1395. return hr;
  1396. }
  1397. return hr;
  1398. }
  1399. STDMETHODIMP
  1400. CFaxDocument::put_AttachFaxToReceipt(
  1401. VARIANT_BOOL bAttachFax
  1402. )
  1403. /*++
  1404. Routine name : CFaxDocument::put_AttachFaxToReceipt
  1405. Routine description:
  1406. Set whether Fax Server should attach the fax to the receipt
  1407. Author:
  1408. Iv Garber (IvG), Dec, 2000
  1409. Arguments:
  1410. bAttachFax [in] - the new value of the Flag
  1411. Return Value:
  1412. Standard HRESULT code
  1413. --*/
  1414. {
  1415. HRESULT hr = S_OK;
  1416. DBG_ENTER (_T("CFaxDocument::put_AttachFaxToReceipt"), hr, _T("%d"), bAttachFax);
  1417. m_bAttachFax = bAttachFax;
  1418. return hr;
  1419. }
  1420. STDMETHODIMP
  1421. CFaxDocument::get_GroupBroadcastReceipts(
  1422. VARIANT_BOOL *pbUseGrouping
  1423. )
  1424. /*++
  1425. Routine name : CFaxDocument::get_GroupBroadcastReceipts
  1426. Routine description:
  1427. Return Flag indicating whether or not Broadcast Receipts are Grouped
  1428. Author:
  1429. Iv Garber (IvG), Apr, 2000
  1430. Arguments:
  1431. pbUseGrouping [out] - the Current value of the Flag
  1432. Return Value:
  1433. Standard HRESULT code
  1434. --*/
  1435. {
  1436. HRESULT hr = S_OK;
  1437. DBG_ENTER (_T("CFaxDocument::get_GroupBroadcastReceipts"), hr);
  1438. hr = GetVariantBool(pbUseGrouping, m_bUseGrouping);
  1439. if (FAILED(hr))
  1440. {
  1441. Error(GetErrorMsgId(hr), IID_IFaxDocument, hr);
  1442. return hr;
  1443. }
  1444. return hr;
  1445. }
  1446. STDMETHODIMP
  1447. CFaxDocument::put_GroupBroadcastReceipts(
  1448. VARIANT_BOOL bUseGrouping
  1449. )
  1450. /*++
  1451. Routine name : CFaxDocument::put_GroupBroadcastReceipts
  1452. Routine description:
  1453. Set Group Broadcast Receipts Flag
  1454. Author:
  1455. Iv Garber (IvG), Apr, 2000
  1456. Arguments:
  1457. bUseGrouping [in] - the new value of the Flag
  1458. Return Value:
  1459. Standard HRESULT code
  1460. --*/
  1461. {
  1462. HRESULT hr = S_OK;
  1463. DBG_ENTER (_T("CFaxDocument::put_GroupBroadcastReceipts"), hr, _T("%d"), bUseGrouping);
  1464. m_bUseGrouping = bUseGrouping;
  1465. return hr;
  1466. }
  1467. STDMETHODIMP
  1468. CFaxDocument::get_Priority(
  1469. FAX_PRIORITY_TYPE_ENUM *pPriority
  1470. )
  1471. /*++
  1472. Routine name : CFaxDocument::get_Priority
  1473. Routine description:
  1474. Return Current Priority of the Document
  1475. Author:
  1476. Iv Garber (IvG), Apr, 2000
  1477. Arguments:
  1478. pPriority [out] - the Current Priority
  1479. Return Value:
  1480. Standard HRESULT code
  1481. --*/
  1482. {
  1483. HRESULT hr = S_OK;
  1484. DBG_ENTER (TEXT("CFaxDocument::get_Priority"), hr);
  1485. //
  1486. // Check that we can write to the given pointer
  1487. //
  1488. if (::IsBadWritePtr(pPriority, sizeof(FAX_PRIORITY_TYPE_ENUM)))
  1489. {
  1490. //
  1491. // Got Bad Return Pointer
  1492. //
  1493. hr = E_POINTER;
  1494. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1495. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr()"), hr);
  1496. return hr;
  1497. }
  1498. *pPriority = m_Priority;
  1499. return hr;
  1500. }
  1501. STDMETHODIMP
  1502. CFaxDocument::put_Priority(
  1503. FAX_PRIORITY_TYPE_ENUM Priority
  1504. )
  1505. /*++
  1506. Routine name : CFaxDocument::put_Priority
  1507. Routine description:
  1508. Set new Priority for the Document
  1509. Author:
  1510. Iv Garber (IvG), Apr, 2000
  1511. Arguments:
  1512. Priority [in] - the new Priority
  1513. Return Value:
  1514. Standard HRESULT code
  1515. --*/
  1516. {
  1517. HRESULT hr = S_OK;
  1518. DBG_ENTER (_T("CFaxDocument::put_Priority"), hr, _T("%d"), Priority);
  1519. if (Priority < fptLOW || Priority > fptHIGH)
  1520. {
  1521. //
  1522. // Out of the Range
  1523. //
  1524. hr = E_INVALIDARG;
  1525. Error(IDS_ERROR_OUTOFRANGE, IID_IFaxDocument, hr);
  1526. CALL_FAIL(GENERAL_ERR, _T("Priority is out of the Range"), hr);
  1527. return hr;
  1528. }
  1529. m_Priority = FAX_PRIORITY_TYPE_ENUM(Priority);
  1530. return hr;
  1531. }
  1532. STDMETHODIMP
  1533. CFaxDocument::get_TapiConnection(
  1534. IDispatch **ppTapiConnection
  1535. )
  1536. /*++
  1537. Routine name : CFaxDocument::get_TapiConnection
  1538. Routine description:
  1539. Return Tapi Connection
  1540. Author:
  1541. Iv Garber (IvG), Apr, 2000
  1542. Arguments:
  1543. ppTapiConnection [out] - the Tapi Connection Interface
  1544. Return Value:
  1545. Standard HRESULT code
  1546. --*/
  1547. {
  1548. HRESULT hr = S_OK;
  1549. DBG_ENTER (TEXT("CFaxDocument::get_TapiConnection"), hr);
  1550. //
  1551. // Check that we can write to the given pointer
  1552. //
  1553. if (::IsBadWritePtr(ppTapiConnection, sizeof(IDispatch *)))
  1554. {
  1555. //
  1556. // Got Bad Return Pointer
  1557. //
  1558. hr = E_POINTER;
  1559. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1560. CALL_FAIL(GENERAL_ERR, _T("IsBadWritePtr()"), hr);
  1561. return hr;
  1562. }
  1563. hr = m_TapiConnection.CopyTo(ppTapiConnection);
  1564. if (FAILED(hr))
  1565. {
  1566. //
  1567. // Failed to Copy Interface
  1568. //
  1569. Error(IDS_ERROR_OPERATION_FAILED, IID_IFaxDocument, hr);
  1570. CALL_FAIL(GENERAL_ERR, _T("CComPtr<IDispatch>::CopyTo()"), hr);
  1571. return hr;
  1572. }
  1573. return hr;
  1574. }
  1575. STDMETHODIMP
  1576. CFaxDocument::putref_TapiConnection(
  1577. IDispatch *pTapiConnection
  1578. )
  1579. {
  1580. HRESULT hr = S_OK;
  1581. DBG_ENTER (_T("CFaxDocument::putref_TapiConnection"), hr, _T("%ld"), pTapiConnection);
  1582. if (!pTapiConnection)
  1583. {
  1584. //
  1585. // Got NULL interface
  1586. //
  1587. hr = E_POINTER;
  1588. Error(IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDocument, hr);
  1589. CALL_FAIL(GENERAL_ERR, _T("!pTapiConnection"), hr);
  1590. return hr;
  1591. }
  1592. m_TapiConnection = pTapiConnection;
  1593. return hr;
  1594. }