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.

1541 lines
34 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. FaxDevice.cpp
  5. Abstract:
  6. Implementation of CFaxDevice class.
  7. Author:
  8. Iv Garber (IvG) Jun, 2000
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "FaxComEx.h"
  13. #include "FaxDevice.h"
  14. #include "..\..\inc\FaxUIConstants.h"
  15. //
  16. //===================== ANSWER CALL ================================================
  17. //
  18. STDMETHODIMP
  19. CFaxDevice::AnswerCall()
  20. /*++
  21. Routine name : CFaxDevice::AnswerCall
  22. Routine description:
  23. Answer a Call when Manual Answer is set ON. The lCallId parameter is received from OnNewCall notification.
  24. Author:
  25. Iv Garber (IvG), Dec, 2000
  26. Arguments:
  27. Return Value:
  28. Standard HRESULT code
  29. --*/
  30. {
  31. HRESULT hr = S_OK;
  32. DBG_ENTER(_T("CFaxDevice::AnswerCall"), hr);
  33. //
  34. // Get Fax Server Handle
  35. //
  36. HANDLE faxHandle;
  37. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  38. ATLASSERT(SUCCEEDED(hr));
  39. if (faxHandle == NULL)
  40. {
  41. //
  42. // Fax Server is not connected
  43. //
  44. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  45. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  46. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  47. return hr;
  48. }
  49. //
  50. // Ask Server to Answer the Call
  51. //
  52. if (!FaxAnswerCall(faxHandle, m_lID))
  53. {
  54. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  55. CALL_FAIL(GENERAL_ERR, _T("FaxAnswerCall(faxHandle, lCallId, m_lID)"), hr);
  56. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  57. return hr;
  58. }
  59. return hr;
  60. }
  61. //
  62. //===================== GET RINGING NOW ================================================
  63. //
  64. STDMETHODIMP
  65. CFaxDevice::get_RingingNow(
  66. /*[out, retval]*/ VARIANT_BOOL *pbRingingNow
  67. )
  68. /*++
  69. Routine name : CFaxDevice::get_RingingNow
  70. Routine description:
  71. Return whether or not the Device was ringing at the moment the properties were taken.
  72. Author:
  73. Iv Garber (IvG), Dec, 2000
  74. Arguments:
  75. pbRingingNow [out] - the result
  76. Return Value:
  77. Standard HRESULT code
  78. --*/
  79. {
  80. HRESULT hr = S_OK;
  81. DBG_ENTER(_T("CFaxDevice::get_RingingNow"), hr);
  82. hr = GetVariantBool(pbRingingNow, bool2VARIANT_BOOL(m_dwStatus & FAX_DEVICE_STATUS_RINGING));
  83. if (FAILED(hr))
  84. {
  85. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  86. return hr;
  87. }
  88. return hr;
  89. };
  90. //
  91. //===================== GET RECEIVING NOW ================================================
  92. //
  93. STDMETHODIMP
  94. CFaxDevice::get_ReceivingNow(
  95. /*[out, retval]*/ VARIANT_BOOL *pbReceivingNow
  96. )
  97. /*++
  98. Routine name : CFaxDevice::get_ReceivingNow
  99. Routine description:
  100. Return whether or not the Device was receiving when the properties were taken.
  101. Author:
  102. Iv Garber (IvG), Jul, 2000
  103. Arguments:
  104. pbReceivingNow [out] - the result
  105. Return Value:
  106. Standard HRESULT code
  107. --*/
  108. {
  109. HRESULT hr = S_OK;
  110. DBG_ENTER(_T("CFaxDevice::get_ReceivingNow"), hr);
  111. hr = GetVariantBool(pbReceivingNow, bool2VARIANT_BOOL(m_dwStatus & FAX_DEVICE_STATUS_RECEIVING));
  112. if (FAILED(hr))
  113. {
  114. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  115. return hr;
  116. }
  117. return hr;
  118. };
  119. //
  120. //===================== GET SENDING NOW ================================================
  121. //
  122. STDMETHODIMP
  123. CFaxDevice::get_SendingNow(
  124. /*[out, retval]*/ VARIANT_BOOL *pbSendingNow
  125. )
  126. /*++
  127. Routine name : CFaxDevice::get_SendingNow
  128. Routine description:
  129. Return whether or not the Device was sending when the properties were taken.
  130. Author:
  131. Iv Garber (IvG), Jul, 2000
  132. Arguments:
  133. pbSendingNow [out] - the result
  134. Return Value:
  135. Standard HRESULT code
  136. --*/
  137. {
  138. HRESULT hr = S_OK;
  139. DBG_ENTER(_T("CFaxDevice::get_SendingNow"), hr);
  140. hr = GetVariantBool(pbSendingNow, bool2VARIANT_BOOL(m_dwStatus & FAX_DEVICE_STATUS_SENDING));
  141. if (FAILED(hr))
  142. {
  143. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  144. return hr;
  145. }
  146. return hr;
  147. };
  148. //
  149. //===================== SET EXTENSION PROPERTY ===============================================
  150. // TODO: should work with empty vProperty
  151. //
  152. STDMETHODIMP
  153. CFaxDevice::SetExtensionProperty(
  154. /*[in]*/ BSTR bstrGUID,
  155. /*[in]*/ VARIANT vProperty
  156. )
  157. /*++
  158. Routine name : CFaxDevice::SetExtensionProperty
  159. Routine description:
  160. Set the Extension Data by given GUID on the Server.
  161. Author:
  162. Iv Garber (IvG), Jun, 2000
  163. Arguments:
  164. bstrGUID [in] -- Extension's Data GUID
  165. vProperty [out] -- Variant with the Blob to Set
  166. Return Value:
  167. Standard HRESULT code
  168. --*/
  169. {
  170. HRESULT hr = S_OK;
  171. DBG_ENTER(_T("CFaxDevice::SetExtensionProperty()"), hr, _T("GUID=%s"), bstrGUID);
  172. hr = ::SetExtensionProperty(m_pIFaxServerInner, m_lID, bstrGUID, vProperty);
  173. if (FAILED(hr))
  174. {
  175. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  176. return hr;
  177. }
  178. return hr;
  179. };
  180. //
  181. //===================== GET EXTENSION PROPERTY ===============================================
  182. //
  183. STDMETHODIMP
  184. CFaxDevice::GetExtensionProperty(
  185. /*[in]*/ BSTR bstrGUID,
  186. /*[out, retval]*/ VARIANT *pvProperty
  187. )
  188. /*++
  189. Routine name : CFaxDevice::GetExtensionProperty
  190. Routine description:
  191. Retrieves the Extension Data by given GUID from the Server.
  192. Author:
  193. Iv Garber (IvG), Jun, 2000
  194. Arguments:
  195. bstrGUID [in] -- Extension's Data GUID
  196. pvProperty [out] -- Variant with the Blob to Return
  197. Return Value:
  198. Standard HRESULT code
  199. --*/
  200. {
  201. HRESULT hr = S_OK;
  202. DBG_ENTER(_T("CFaxDevice::GetExtensionProperty()"), hr, _T("GUID=%s"), bstrGUID);
  203. hr = ::GetExtensionProperty(m_pIFaxServerInner, m_lID, bstrGUID, pvProperty);
  204. if (FAILED(hr))
  205. {
  206. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  207. return hr;
  208. }
  209. return hr;
  210. };
  211. //
  212. //===================== USE ROUTING METHOD ===============================================
  213. //
  214. STDMETHODIMP
  215. CFaxDevice::UseRoutingMethod(
  216. /*[in]*/ BSTR bstrMethodGUID,
  217. /*[in]*/ VARIANT_BOOL bUse
  218. )
  219. /*++
  220. Routine name : CFaxDevice::UseRoutingMethod
  221. Routine description:
  222. Add/Remove Routing Method for the Device.
  223. Author:
  224. Iv Garber (IvG), Jun, 2000
  225. Arguments:
  226. bstrMethodGUID [in] -- Method to Add/Remove
  227. bUse [in] -- Add or Remove Operation Indicator
  228. Return Value:
  229. Standard HRESULT code
  230. --*/
  231. {
  232. HRESULT hr = S_OK;
  233. DBG_ENTER(_T("CFaxDevice::UseRoutingMethod()"), hr, _T("MethodGUID=%s, bUse=%d"), bstrMethodGUID, bUse);
  234. //
  235. // Get Fax Server Handle
  236. //
  237. HANDLE faxHandle;
  238. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  239. ATLASSERT(SUCCEEDED(hr));
  240. if (faxHandle == NULL)
  241. {
  242. //
  243. // Fax Server is not connected
  244. //
  245. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  246. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  247. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  248. return hr;
  249. }
  250. //
  251. // Open Port for the Device
  252. //
  253. HANDLE hPort;
  254. if (!FaxOpenPort(faxHandle, m_lID, PORT_OPEN_MODIFY, &hPort))
  255. {
  256. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  257. CALL_FAIL(GENERAL_ERR, _T("FaxOpenPort(faxHandle, m_lID, PORT_OPEN_QUERY, &hPort)"), hr);
  258. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  259. return hr;
  260. }
  261. ATLASSERT(hPort);
  262. //
  263. // Ask Server to Add/Remove the Method for the Device
  264. //
  265. if (!FaxEnableRoutingMethod(hPort, bstrMethodGUID, VARIANT_BOOL2bool(bUse)))
  266. {
  267. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  268. CALL_FAIL(GENERAL_ERR, _T("FaxEnableRoutingMethod(faxHandle, bstrMethodGUID, VARIANT_BOOL2bool(bUse))"), hr);
  269. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  270. goto exit;
  271. }
  272. exit:
  273. if (!FaxClose(hPort))
  274. {
  275. CALL_FAIL(GENERAL_ERR, _T("FaxClose(hPort)"), Fax_HRESULT_FROM_WIN32(GetLastError()));
  276. }
  277. //
  278. // no need to store change locally, because each time get_UsedRoutingMethods is used,
  279. // it brings the updated data from the Server.
  280. //
  281. return hr;
  282. } // CFaxDevice::UseRoutingMethod
  283. //
  284. //===================== SAVE ===============================================
  285. //
  286. STDMETHODIMP
  287. CFaxDevice::Save()
  288. /*++
  289. Routine name : CFaxDevice::Save
  290. Routine description:
  291. Save the data of the Device to the Server.
  292. Author:
  293. Iv Garber (IvG), Jun, 2000
  294. Arguments:
  295. Return Value:
  296. Standard HRESULT code
  297. --*/
  298. {
  299. HRESULT hr = S_OK;
  300. DBG_ENTER(_T("CFaxDevice::Save()"), hr);
  301. //
  302. // Get Fax Server Handle
  303. //
  304. HANDLE faxHandle;
  305. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  306. ATLASSERT(SUCCEEDED(hr));
  307. if (faxHandle == NULL)
  308. {
  309. //
  310. // Fax Server is not connected
  311. //
  312. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  313. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  314. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  315. return hr;
  316. }
  317. //
  318. // Create FAX_PORT_INFO struct and fill it with the values
  319. //
  320. FAX_PORT_INFO_EX Data = {0};
  321. Data.ReceiveMode = m_ReceiveMode;
  322. Data.bSend = m_bSendEnabled;
  323. Data.dwRings = m_lRings;
  324. Data.dwSizeOfStruct = sizeof(FAX_PORT_INFO_EX);
  325. Data.lptstrCsid = m_bstrCSID;
  326. Data.lptstrDescription = m_bstrDescr;
  327. Data.lptstrTsid = m_bstrTSID;
  328. //
  329. // Save the Data struct on Server
  330. //
  331. if (!FaxSetPortEx(faxHandle, m_lID, &Data))
  332. {
  333. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  334. CALL_FAIL(GENERAL_ERR, _T("FaxSetPortEx(faxHandle, m_lID, &Data)"), hr);
  335. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  336. return hr;
  337. }
  338. return hr;
  339. };
  340. //
  341. //===================== REFRESH ===============================================
  342. //
  343. STDMETHODIMP
  344. CFaxDevice::Refresh()
  345. /*++
  346. Routine name : CFaxDevice::Refresh
  347. Routine description:
  348. Bring from the Server data for the Device.
  349. Author:
  350. Iv Garber (IvG), Jun, 2000
  351. Arguments:
  352. Return Value:
  353. Standard HRESULT code
  354. --*/
  355. {
  356. HRESULT hr = S_OK;
  357. DBG_ENTER(_T("CFaxDevice::Refresh()"), hr);
  358. //
  359. // Get Fax Server Handle
  360. //
  361. HANDLE faxHandle;
  362. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  363. ATLASSERT(SUCCEEDED(hr));
  364. if (faxHandle == NULL)
  365. {
  366. //
  367. // Fax Server is not connected
  368. //
  369. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  370. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  371. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  372. return hr;
  373. }
  374. //
  375. // Ask Server for Data about Device
  376. //
  377. CFaxPtr<FAX_PORT_INFO_EX> pDevice;
  378. if (!FaxGetPortEx(faxHandle, m_lID, &pDevice))
  379. {
  380. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  381. CALL_FAIL(GENERAL_ERR, _T("FaxGetPortEx(faxHandle, m_lId, &pDevice)"), hr);
  382. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  383. return hr;
  384. }
  385. hr = Init(pDevice, NULL);
  386. return hr;
  387. };
  388. //
  389. //================== GET USED ROUTING METHODS ==================================
  390. //
  391. STDMETHODIMP
  392. CFaxDevice::get_UsedRoutingMethods(
  393. /*[out, retval]*/ VARIANT *pvUsedRoutingMethods
  394. )
  395. /*++
  396. Routine name : CFaxDevice::get_UsedRoutingMethods
  397. Routine description:
  398. Return Variant containing the SafeArray of Used by the Device Routing Methods GUIDs.
  399. Author:
  400. Iv Garber (IvG), Jun, 2000
  401. Arguments:
  402. pvUsedRoutingMethods [out] - the Variant containing the Result
  403. Return Value:
  404. Standard HRESULT code
  405. --*/
  406. {
  407. HRESULT hr = S_OK;
  408. DBG_ENTER(_T("CFaxDevice::get_UsedRoutingMethods"), hr);
  409. //
  410. // Get Fax Server Handle
  411. //
  412. HANDLE faxHandle;
  413. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  414. ATLASSERT(SUCCEEDED(hr));
  415. if (faxHandle == NULL)
  416. {
  417. //
  418. // Fax Server is not connected
  419. //
  420. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  421. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  422. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  423. return hr;
  424. }
  425. //
  426. // Open Port for the Device
  427. //
  428. HANDLE portHandle;
  429. if (!FaxOpenPort(faxHandle, m_lID, PORT_OPEN_QUERY, &portHandle))
  430. {
  431. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  432. CALL_FAIL(GENERAL_ERR, _T("FaxOpenPort(faxHandle, m_lID, PORT_OPEN_QUERY, &portHandle)"), hr);
  433. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  434. return hr;
  435. }
  436. ATLASSERT(portHandle);
  437. //
  438. // Bring from the Server all Device's Routing Methods
  439. //
  440. DWORD dwNum = 0;
  441. CFaxPtr<FAX_ROUTING_METHOD> pMethods;
  442. BOOL bResult = FaxEnumRoutingMethods(portHandle, &pMethods, &dwNum);
  443. if (!bResult)
  444. {
  445. hr = Fax_HRESULT_FROM_WIN32(GetLastError());
  446. CALL_FAIL(GENERAL_ERR, _T("FaxEnumRoutingMethods(portHandle, &pMethods, &dwNum)"), hr);
  447. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  448. if (!FaxClose(portHandle))
  449. {
  450. CALL_FAIL(GENERAL_ERR, _T("FaxClose(portHandle)"), Fax_HRESULT_FROM_WIN32(GetLastError()));
  451. }
  452. return hr;
  453. }
  454. if (!FaxClose(portHandle))
  455. {
  456. CALL_FAIL(GENERAL_ERR, _T("FaxClose(portHandle)"), Fax_HRESULT_FROM_WIN32(GetLastError()));
  457. }
  458. //
  459. // count the enabled routing methods
  460. //
  461. DWORD dwCount = 0;
  462. for ( DWORD i=0 ; i<dwNum ; i++ )
  463. {
  464. if (pMethods[i].Enabled)
  465. {
  466. dwCount++;
  467. }
  468. }
  469. //
  470. // Create SafeArray for Enabled Routing Methods
  471. //
  472. SAFEARRAY *psaGUIDs;
  473. psaGUIDs = ::SafeArrayCreateVector(VT_BSTR, 0, dwCount);
  474. if (!psaGUIDs)
  475. {
  476. hr = E_FAIL;
  477. CALL_FAIL(GENERAL_ERR, _T("SafeArrayCreateVector(VT_BSTR, 0, dwCount)"), hr);
  478. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  479. return hr;
  480. }
  481. //
  482. // Got Access to the SafeArray
  483. //
  484. BSTR *pbstrElement;
  485. hr = ::SafeArrayAccessData(psaGUIDs, (void **) &pbstrElement);
  486. if (FAILED(hr))
  487. {
  488. hr = E_FAIL;
  489. CALL_FAIL(GENERAL_ERR, _T("::SafeArrayAccessData(psaGUIDs, &pbstrElement)"), hr);
  490. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  491. ::SafeArrayDestroy(psaGUIDs);
  492. return hr;
  493. }
  494. //
  495. // Put Methods GUIDs into the SafeArray
  496. //
  497. DWORD j=0;
  498. for ( i=0 ; i<dwNum ; i++ )
  499. {
  500. if (pMethods[i].Enabled)
  501. {
  502. pbstrElement[j] = ::SysAllocString(pMethods[i].Guid);
  503. if (pMethods[i].Guid && !pbstrElement[j])
  504. {
  505. //
  506. // Not Enough Memory
  507. //
  508. hr = E_OUTOFMEMORY;
  509. CALL_FAIL(MEM_ERR, _T("::SysAllocString(pMethods[i])"), hr);
  510. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  511. ::SafeArrayUnaccessData(psaGUIDs);
  512. ::SafeArrayDestroy(psaGUIDs);
  513. return hr;
  514. }
  515. j++;
  516. }
  517. }
  518. //
  519. // Unaccess the SafeArray
  520. //
  521. hr = ::SafeArrayUnaccessData(psaGUIDs);
  522. if (FAILED(hr))
  523. {
  524. CALL_FAIL(GENERAL_ERR, _T("::SafeArrayUnaccessData(psaGUIDs)"), hr);
  525. }
  526. //
  527. // Put the SafeArray we created into the given Variant
  528. //
  529. VariantInit(pvUsedRoutingMethods);
  530. pvUsedRoutingMethods->vt = VT_BSTR | VT_ARRAY;
  531. pvUsedRoutingMethods->parray = psaGUIDs;
  532. return hr;
  533. };
  534. //
  535. //================= PUT DESCRIPTION ======================================
  536. //
  537. STDMETHODIMP
  538. CFaxDevice::put_Description(
  539. /*[in]*/ BSTR bstrDescription
  540. )
  541. /*++
  542. Routine name : CFaxDevice::put_Description
  543. Routine description:
  544. Set Description
  545. Author:
  546. Iv Garber (IvG), Jun, 2000
  547. Arguments:
  548. bstrDescription [in] - new Description
  549. Return Value:
  550. Standard HRESULT code
  551. --*/
  552. {
  553. HRESULT hr = S_OK;
  554. DBG_ENTER (_T("CFaxDevice::put_Description"), hr, _T("Value=%s"), bstrDescription);
  555. m_bstrDescr = bstrDescription;
  556. if (!m_bstrDescr && bstrDescription)
  557. {
  558. //
  559. // Not enough memory
  560. //
  561. hr = E_OUTOFMEMORY;
  562. AtlReportError(CLSID_FaxDevice, IDS_ERROR_OUTOFMEMORY, IID_IFaxDevice, hr);
  563. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  564. return hr;
  565. }
  566. return hr;
  567. }
  568. //
  569. //================= PUT CSID ======================================
  570. //
  571. STDMETHODIMP
  572. CFaxDevice::put_CSID (
  573. /*[in]*/ BSTR bstrCSID
  574. )
  575. /*++
  576. Routine name : CFaxDevice::put_CSID
  577. Routine description:
  578. Set CSID
  579. Author:
  580. Iv Garber (IvG), Jun, 2000
  581. Arguments:
  582. bstrCSID [in] - new TSID
  583. Return Value:
  584. Standard HRESULT code
  585. --*/
  586. {
  587. HRESULT hr = S_OK;
  588. DBG_ENTER (_T("CFaxDevice::put_CSID"), hr, _T("Value=%s"), bstrCSID);
  589. if (SysStringLen(bstrCSID) > FXS_TSID_CSID_MAX_LENGTH)
  590. {
  591. //
  592. // Out of the Range
  593. //
  594. hr = E_INVALIDARG;
  595. AtlReportError(CLSID_FaxDevice, IDS_ERROR_OUTOFRANGE, IID_IFaxDevice, hr);
  596. CALL_FAIL(GENERAL_ERR, _T("TSID is too long"), hr);
  597. return hr;
  598. }
  599. m_bstrCSID = bstrCSID;
  600. if (!m_bstrCSID && bstrCSID)
  601. {
  602. //
  603. // Not enough memory
  604. //
  605. hr = E_OUTOFMEMORY;
  606. AtlReportError(CLSID_FaxDevice, IDS_ERROR_OUTOFMEMORY, IID_IFaxDevice, hr);
  607. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  608. return hr;
  609. }
  610. return hr;
  611. }
  612. //
  613. //================= PUT TSID ======================================
  614. //
  615. STDMETHODIMP
  616. CFaxDevice::put_TSID (
  617. /*[in]*/ BSTR bstrTSID
  618. )
  619. /*++
  620. Routine name : CFaxDevice::put_TSID
  621. Routine description:
  622. Set TSID
  623. Author:
  624. Iv Garber (IvG), Jun, 2000
  625. Arguments:
  626. bstrTSID [in] - new TSID
  627. Return Value:
  628. Standard HRESULT code
  629. --*/
  630. {
  631. HRESULT hr = S_OK;
  632. DBG_ENTER (_T("CFaxDevice::put_TSID"), hr, _T("Value=%s"), bstrTSID);
  633. if (SysStringLen(bstrTSID) > FXS_TSID_CSID_MAX_LENGTH)
  634. {
  635. //
  636. // Out of the Range
  637. //
  638. hr = E_INVALIDARG;
  639. AtlReportError(CLSID_FaxDevice, IDS_ERROR_OUTOFRANGE, IID_IFaxDevice, hr);
  640. CALL_FAIL(GENERAL_ERR, _T("TSID is too long"), hr);
  641. return hr;
  642. }
  643. m_bstrTSID = bstrTSID;
  644. if (!m_bstrTSID && bstrTSID)
  645. {
  646. //
  647. // Not enough memory
  648. //
  649. hr = E_OUTOFMEMORY;
  650. AtlReportError(CLSID_FaxDevice, IDS_ERROR_OUTOFMEMORY, IID_IFaxDevice, hr);
  651. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator="), hr);
  652. return hr;
  653. }
  654. return hr;
  655. }
  656. //
  657. //=============== PUT RECEIVE MODE =====================================================
  658. //
  659. STDMETHODIMP
  660. CFaxDevice::put_ReceiveMode(
  661. /*[in]*/ FAX_DEVICE_RECEIVE_MODE_ENUM ReceiveMode
  662. )
  663. /*++
  664. Routine name : CFaxDevice::put_ReceiveMode
  665. Routine description:
  666. Set New Value of Receive Mode Attribute for Device Object.
  667. Author:
  668. Iv Garber (IvG), Aug, 2000
  669. Arguments:
  670. ReceiveMode [in] - the new value to set
  671. Return Value:
  672. Standard HRESULT code
  673. --*/
  674. {
  675. HRESULT hr = S_OK;
  676. DBG_ENTER(_T("CFaxDevice::put_ReceiveMode"), hr, _T("Value=%d"), ReceiveMode);
  677. //
  678. // Set receive mode
  679. //
  680. if ((ReceiveMode > fdrmMANUAL_ANSWER) || (ReceiveMode < fdrmNO_ANSWER))
  681. {
  682. hr = E_INVALIDARG;
  683. AtlReportError(CLSID_FaxDevice, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDevice, hr);
  684. CALL_FAIL(GENERAL_ERR, _T("ReceiveMode > fdrmMANUAL_ANSWER"), hr);
  685. return hr;
  686. }
  687. if (fdrmMANUAL_ANSWER == ReceiveMode)
  688. {
  689. //
  690. // Check to see if the device is virtual
  691. // Get Fax Server Handle
  692. //
  693. HANDLE faxHandle;
  694. hr = m_pIFaxServerInner->GetHandle(&faxHandle);
  695. ATLASSERT(SUCCEEDED(hr));
  696. if (faxHandle == NULL)
  697. {
  698. //
  699. // Fax Server is not connected
  700. //
  701. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED);
  702. CALL_FAIL(GENERAL_ERR, _T("faxHandle == NULL"), hr);
  703. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  704. return hr;
  705. }
  706. BOOL bVirtual;
  707. DWORD dwRes = IsDeviceVirtual (faxHandle, m_lID, &bVirtual);
  708. if (ERROR_SUCCESS != dwRes)
  709. {
  710. hr = Fax_HRESULT_FROM_WIN32(dwRes);
  711. CALL_FAIL(GENERAL_ERR, _T("IsDeviceVirtual"), hr);
  712. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  713. return hr;
  714. }
  715. if (bVirtual)
  716. {
  717. //
  718. // Virtual devices cannot be set to manual-answer mode
  719. //
  720. hr = Fax_HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
  721. CALL_FAIL(GENERAL_ERR, _T("IsDeviceVirtual"), hr);
  722. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  723. return hr;
  724. }
  725. }
  726. m_ReceiveMode = FAX_ENUM_DEVICE_RECEIVE_MODE (ReceiveMode);
  727. return hr;
  728. }
  729. //
  730. //=============== PUT SEND ENABLED ==================================================
  731. //
  732. STDMETHODIMP
  733. CFaxDevice::put_SendEnabled(
  734. /*[in]*/ VARIANT_BOOL bSendEnabled
  735. )
  736. /*++
  737. Routine name : CFaxDevice::put_SendEnabled
  738. Routine description:
  739. Set New Value for Send Property for Device Object.
  740. Author:
  741. Iv Garber (IvG), Jun, 2000
  742. Arguments:
  743. bSendEnabled [in] - the new value to set
  744. Return Value:
  745. Standard HRESULT code
  746. --*/
  747. {
  748. HRESULT hr = S_OK;
  749. DBG_ENTER(_T("CFaxDevice::put_SendEnabled"), hr, _T("Value=%d"), bSendEnabled);
  750. m_bSendEnabled = VARIANT_BOOL2bool(bSendEnabled);
  751. return hr;
  752. }
  753. //
  754. //=============== PUT RINGS BEFORE ANSWER ======================================
  755. //
  756. STDMETHODIMP
  757. CFaxDevice::put_RingsBeforeAnswer(
  758. /*[in]*/ long lRings
  759. )
  760. /*++
  761. Routine name : CFaxDevice::put_RingsBeforeAnswer
  762. Routine description:
  763. Set New Value for the Rings Before Answer Property for Device Object
  764. Author:
  765. Iv Garber (IvG), Jun, 2000
  766. Arguments:
  767. lRings [in] - the new value to set
  768. Return Value:
  769. Standard HRESULT code
  770. --*/
  771. {
  772. HRESULT hr = S_OK;
  773. DBG_ENTER(_T("CFaxDevice::put_RingsBeforeAnswer)"), hr, _T("Value=%d"), lRings);
  774. if (lRings < FXS_RINGS_LOWER || lRings > FXS_RINGS_UPPER)
  775. {
  776. hr = E_INVALIDARG;
  777. AtlReportError(CLSID_FaxDevice, IDS_ERROR_INVALID_ARGUMENT, IID_IFaxDevice, hr);
  778. CALL_FAIL(GENERAL_ERR, _T("lRings<0"), hr);
  779. return hr;
  780. }
  781. m_lRings = lRings;
  782. return hr;
  783. };
  784. //
  785. //===================== GET CSID ================================================
  786. //
  787. STDMETHODIMP
  788. CFaxDevice::get_CSID(
  789. /*[out, retval]*/ BSTR *pbstrCSID
  790. )
  791. /*++
  792. Routine name : CFaxDevice::get_CSID
  793. Routine description:
  794. Return the Device's CSID.
  795. Author:
  796. Iv Garber (IvG), Jun, 2000
  797. Arguments:
  798. pbstrCSID [out] - the Ptr where to put the value
  799. Return Value:
  800. Standard HRESULT code
  801. --*/
  802. {
  803. HRESULT hr = S_OK;
  804. DBG_ENTER(_T("CFaxDevice::get_CSID"), hr);
  805. hr = GetBstr(pbstrCSID, m_bstrCSID);
  806. if (FAILED(hr))
  807. {
  808. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  809. return hr;
  810. }
  811. return hr;
  812. }
  813. //
  814. //===================== GET TSID ================================================
  815. //
  816. STDMETHODIMP
  817. CFaxDevice::get_TSID(
  818. /*[out, retval]*/ BSTR *pbstrTSID
  819. )
  820. /*++
  821. Routine name : CFaxDevice::get_TSID
  822. Routine description:
  823. Return the Device's TSID.
  824. Author:
  825. Iv Garber (IvG), Jun, 2000
  826. Arguments:
  827. pbstrTSID [out] - the Ptr where to put the value
  828. Return Value:
  829. Standard HRESULT code
  830. --*/
  831. {
  832. HRESULT hr = S_OK;
  833. DBG_ENTER(_T("CFaxDevice::get_TSID"), hr);
  834. hr = GetBstr(pbstrTSID, m_bstrTSID);
  835. if (FAILED(hr))
  836. {
  837. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  838. return hr;
  839. }
  840. return hr;
  841. }
  842. //
  843. //===================== GET RECEIVE MODE =============================================
  844. //
  845. STDMETHODIMP
  846. CFaxDevice::get_ReceiveMode(
  847. /*[out, retval]*/ FAX_DEVICE_RECEIVE_MODE_ENUM *pReceiveMode
  848. )
  849. /*++
  850. Routine name : CFaxDevice::get_ReceiveMode
  851. Routine description:
  852. Return the Device's Receive Mode Attribute.
  853. Author:
  854. Iv Garber (IvG), Aug, 2000
  855. Arguments:
  856. pReceiveMode [out] - the value
  857. Return Value:
  858. Standard HRESULT code
  859. --*/
  860. {
  861. HRESULT hr = S_OK;
  862. DBG_ENTER(_T("CFaxDevice::get_ReceiveMode"), hr);
  863. if (::IsBadWritePtr(pReceiveMode, sizeof(FAX_DEVICE_RECEIVE_MODE_ENUM)))
  864. {
  865. hr = E_POINTER;
  866. CALL_FAIL(GENERAL_ERR, _T("::IsBadWritePtr(pReceiveMode, sizeof(FAX_DEVICE_RECEIVE_MODE_ENUM))"), hr);
  867. return hr;
  868. }
  869. *pReceiveMode = (FAX_DEVICE_RECEIVE_MODE_ENUM) m_ReceiveMode;
  870. return hr;
  871. };
  872. //
  873. //===================== GET SEND ENABLED ============================================
  874. //
  875. STDMETHODIMP
  876. CFaxDevice::get_SendEnabled(
  877. /*[out, retval]*/ VARIANT_BOOL *pbSendEnabled
  878. )
  879. /*++
  880. Routine name : CFaxDevice::get_SendEnabled
  881. Routine description:
  882. Return the Device's Send Attribute.
  883. Author:
  884. Iv Garber (IvG), Jun, 2000
  885. Arguments:
  886. pbSendEnabled [out] - the value
  887. Return Value:
  888. Standard HRESULT code
  889. --*/
  890. {
  891. HRESULT hr = S_OK;
  892. DBG_ENTER(_T("CFaxDevice::get_SendEnabled"), hr);
  893. hr = GetVariantBool(pbSendEnabled, bool2VARIANT_BOOL(m_bSendEnabled));
  894. if (FAILED(hr))
  895. {
  896. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  897. }
  898. return hr;
  899. };
  900. //
  901. //===================== GET DESCRIPTION ================================================
  902. //
  903. STDMETHODIMP
  904. CFaxDevice::get_Description(
  905. /*[out, retval]*/ BSTR *pbstrDescription
  906. )
  907. /*++
  908. Routine name : CFaxDevice::get_Description
  909. Routine description:
  910. Return the Device's Description.
  911. Author:
  912. Iv Garber (IvG), Jun, 2000
  913. Arguments:
  914. pbstrDescription [out] - the Ptr where to put the value
  915. Return Value:
  916. Standard HRESULT code
  917. --*/
  918. {
  919. HRESULT hr = S_OK;
  920. DBG_ENTER(_T("CFaxDevice::get_Description"), hr);
  921. hr = GetBstr(pbstrDescription, m_bstrDescr);
  922. if (FAILED(hr))
  923. {
  924. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  925. }
  926. return hr;
  927. }
  928. //
  929. //===================== GET POWERED OFF ================================================
  930. //
  931. STDMETHODIMP
  932. CFaxDevice::get_PoweredOff(
  933. /*[out, retval]*/ VARIANT_BOOL *pbPoweredOff
  934. )
  935. /*++
  936. Routine name : CFaxDevice::get_PoweredOff
  937. Routine description:
  938. Return the Device's Powered Off Attribute.
  939. Author:
  940. Iv Garber (IvG), Jun, 2000
  941. Arguments:
  942. pbPoweredOff [out] - the value
  943. Return Value:
  944. Standard HRESULT code
  945. --*/
  946. {
  947. HRESULT hr = S_OK;
  948. DBG_ENTER(_T("CFaxDevice::get_PoweredOff"), hr);
  949. hr = GetVariantBool(pbPoweredOff, bool2VARIANT_BOOL(m_dwStatus & FAX_DEVICE_STATUS_POWERED_OFF));
  950. if (FAILED(hr))
  951. {
  952. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  953. }
  954. return hr;
  955. };
  956. //
  957. //===================== GET PROVIDER UNIQUE NAME ================================================
  958. //
  959. STDMETHODIMP
  960. CFaxDevice::get_ProviderUniqueName(
  961. /*[out, retval]*/ BSTR *pbstrProviderUniqueName
  962. )
  963. /*++
  964. Routine name : CFaxDevice::get_ProviderUniqueName
  965. Routine description:
  966. Return the Device Provider's Unique Name.
  967. Author:
  968. Iv Garber (IvG), Jun, 2000
  969. Arguments:
  970. pbstrProviderUniqueName [out] - the Ptr where to put the value
  971. Return Value:
  972. Standard HRESULT code
  973. --*/
  974. {
  975. HRESULT hr = S_OK;
  976. DBG_ENTER(_T("CFaxDevice::get_ProviderUniqueName"), hr);
  977. hr = GetBstr(pbstrProviderUniqueName, m_bstrProviderUniqueName);
  978. if (FAILED(hr))
  979. {
  980. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  981. }
  982. return hr;
  983. }
  984. //
  985. //===================== GET DEVICE NAME ================================================
  986. //
  987. STDMETHODIMP
  988. CFaxDevice::get_DeviceName(
  989. /*[out, retval]*/ BSTR *pbstrDeviceName
  990. )
  991. /*++
  992. Routine name : CFaxDevice::get_DeviceName
  993. Routine description:
  994. Return the Device's Name.
  995. Author:
  996. Iv Garber (IvG), Jun, 2000
  997. Arguments:
  998. pbstrDeviceName [out] - the Ptr where to put the value
  999. Return Value:
  1000. Standard HRESULT code
  1001. --*/
  1002. {
  1003. HRESULT hr = S_OK;
  1004. DBG_ENTER(_T("CFaxDevice::get_DeviceName"), hr);
  1005. hr = GetBstr(pbstrDeviceName, m_bstrDeviceName);
  1006. if (FAILED(hr))
  1007. {
  1008. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  1009. }
  1010. return hr;
  1011. }
  1012. //
  1013. //===================== GET RINGS BEFORE ANSWER ================================================
  1014. //
  1015. STDMETHODIMP
  1016. CFaxDevice::get_RingsBeforeAnswer(
  1017. /*[out, retval]*/ long *plRingsBeforeAnswer
  1018. )
  1019. /*++
  1020. Routine name : CFaxDevice::get_RingsBeforeAnswer
  1021. Routine description:
  1022. Return the Device's Number of Rings Before the Answer.
  1023. Author:
  1024. Iv Garber (IvG), Jun, 2000
  1025. Arguments:
  1026. plRingsBeforeAnswer [out] - the Number of Device Rings
  1027. Return Value:
  1028. Standard HRESULT code
  1029. --*/
  1030. {
  1031. HRESULT hr = S_OK;
  1032. DBG_ENTER(_T("CFaxDevice::get_RingsBeforeAnswer"), hr);
  1033. hr = GetLong(plRingsBeforeAnswer, m_lRings);
  1034. if (FAILED(hr))
  1035. {
  1036. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  1037. }
  1038. return hr;
  1039. };
  1040. //
  1041. //===================== GET ID ================================================
  1042. //
  1043. STDMETHODIMP
  1044. CFaxDevice::get_Id(
  1045. /*[out, retval]*/ long *plId
  1046. )
  1047. /*++
  1048. Routine name : CFaxDevice::get_Id
  1049. Routine description:
  1050. Return the Device Id.
  1051. Author:
  1052. Iv Garber (IvG), Jun, 2000
  1053. Arguments:
  1054. plId [out] - the Device ID
  1055. Return Value:
  1056. Standard HRESULT code
  1057. --*/
  1058. {
  1059. HRESULT hr = S_OK;
  1060. DBG_ENTER(_T("CFaxDevice::get_Id"), hr);
  1061. hr = GetLong(plId, m_lID);
  1062. if (FAILED(hr))
  1063. {
  1064. AtlReportError(CLSID_FaxDevice, GetErrorMsgId(hr), IID_IFaxDevice, hr);
  1065. }
  1066. return hr;
  1067. };
  1068. //
  1069. //========================= INIT ==============================================
  1070. //
  1071. STDMETHODIMP
  1072. CFaxDevice::Init(
  1073. FAX_PORT_INFO_EX *pInfo,
  1074. IFaxServerInner *pServer
  1075. )
  1076. /*++
  1077. Routine name : CFaxDevice::Init
  1078. Routine description:
  1079. Initialize the Object with the given data.
  1080. Author:
  1081. Iv Garber (IvG), Jun, 2000
  1082. Arguments:
  1083. pInfo [in] - Ptr to the Device's Data.
  1084. pServer [in] - Ptr to the Fax Server.
  1085. Return Value:
  1086. Standard HRESULT code
  1087. --*/
  1088. {
  1089. HRESULT hr = S_OK;
  1090. DBG_ENTER(_T("CFaxDevice::Init"), hr);
  1091. //
  1092. // Store different Device Fields
  1093. //
  1094. m_lID = pInfo->dwDeviceID;
  1095. m_lRings = pInfo->dwRings;
  1096. m_bSendEnabled = pInfo->bSend;
  1097. m_ReceiveMode = pInfo->ReceiveMode;
  1098. m_dwStatus = pInfo->dwStatus;
  1099. m_bstrDescr = pInfo->lptstrDescription;
  1100. m_bstrProviderUniqueName = pInfo->lpctstrProviderGUID;
  1101. m_bstrDeviceName = pInfo->lpctstrDeviceName;
  1102. m_bstrTSID = pInfo->lptstrTsid;
  1103. m_bstrCSID = pInfo->lptstrCsid;
  1104. if ( (pInfo->lptstrDescription && !m_bstrDescr) ||
  1105. (pInfo->lpctstrProviderGUID && !m_bstrProviderUniqueName) ||
  1106. (pInfo->lptstrTsid && !m_bstrTSID) ||
  1107. (pInfo->lpctstrDeviceName && !m_bstrDeviceName) ||
  1108. (pInfo->lptstrCsid && !m_bstrCSID) )
  1109. {
  1110. hr = E_OUTOFMEMORY;
  1111. CALL_FAIL(MEM_ERR, _T("CComBSTR::operator=()"), hr);
  1112. AtlReportError(CLSID_FaxDevice, IDS_ERROR_OUTOFMEMORY, IID_IFaxDevice, hr);
  1113. return hr;
  1114. }
  1115. if (pServer)
  1116. {
  1117. //
  1118. // Store Ptr to Fax Server Object
  1119. //
  1120. hr = CFaxInitInnerAddRef::Init(pServer);
  1121. }
  1122. return hr;
  1123. }
  1124. //
  1125. //========================= SUPPORT ERROR INFO ====================================
  1126. //
  1127. STDMETHODIMP
  1128. CFaxDevice::InterfaceSupportsErrorInfo(
  1129. REFIID riid
  1130. )
  1131. /*++
  1132. Routine name : CFaxDevice::InterfaceSupportsErrorInfo
  1133. Routine description:
  1134. ATL's implementation of Support Error Info.
  1135. Author:
  1136. Iv Garber (IvG), Jun, 2000
  1137. Arguments:
  1138. riid [in] - Reference to the Interface.
  1139. Return Value:
  1140. Standard HRESULT code
  1141. --*/
  1142. {
  1143. static const IID* arr[] =
  1144. {
  1145. &IID_IFaxDevice
  1146. };
  1147. for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
  1148. {
  1149. if (InlineIsEqualGUID(*arr[i],riid))
  1150. return S_OK;
  1151. }
  1152. return S_FALSE;
  1153. }