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.

765 lines
14 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. faxport.cpp
  5. Abstract:
  6. This module implements the port interface/object.
  7. Author:
  8. Wesley Witt (wesw) 20-May-1997
  9. Revision History:
  10. --*/
  11. #include "stdafx.h"
  12. #include "faxport.h"
  13. #include "faxroute.h"
  14. #include "status.h"
  15. CFaxPort::CFaxPort()
  16. {
  17. m_pFaxServer = NULL;
  18. m_FaxPortHandle = NULL;
  19. m_LastFaxError = NO_ERROR;
  20. m_DeviceId = 0;
  21. m_Rings = 0;
  22. m_Send = FALSE;
  23. m_Receive = FALSE;
  24. m_Name = NULL;
  25. m_Csid = NULL;
  26. m_Tsid = NULL;
  27. m_Modify = FALSE;
  28. }
  29. CFaxPort::~CFaxPort()
  30. {
  31. if (m_FaxPortHandle) {
  32. FaxClose( m_FaxPortHandle );
  33. }
  34. if (m_pFaxServer) {
  35. m_pFaxServer->Release();
  36. }
  37. if (m_Name) {
  38. SysFreeString( m_Name );
  39. }
  40. if (m_Csid) {
  41. SysFreeString( m_Csid );
  42. }
  43. if (m_Tsid) {
  44. SysFreeString( m_Tsid );
  45. }
  46. }
  47. BOOL
  48. CFaxPort::Initialize(
  49. CFaxServer *i_pFaxServer,
  50. DWORD i_DeviceId,
  51. DWORD i_Rings,
  52. DWORD i_Priority,
  53. DWORD i_Flags,
  54. LPCWSTR i_Csid,
  55. LPCWSTR i_Tsid,
  56. LPCWSTR i_DeviceName
  57. )
  58. {
  59. HRESULT hr;
  60. m_pFaxServer = i_pFaxServer;
  61. m_DeviceId = i_DeviceId;
  62. m_Rings = i_Rings;
  63. m_Priority = i_Priority;
  64. m_Csid = SysAllocString( i_Csid);
  65. m_Tsid = SysAllocString( i_Tsid);
  66. m_Name = SysAllocString( i_DeviceName );
  67. m_Send = i_Flags & FPF_SEND;
  68. m_Receive = i_Flags & FPF_RECEIVE;
  69. if ((!m_Csid && i_Csid) ||
  70. (!m_Tsid && i_Tsid) ||
  71. (!m_Name && i_DeviceName)) {
  72. SysFreeString( m_Csid );
  73. SysFreeString( m_Tsid );
  74. SysFreeString( m_Name );
  75. return FALSE;
  76. }
  77. if (!m_pFaxServer) {
  78. return FALSE;
  79. }
  80. hr = m_pFaxServer->AddRef();
  81. if (FAILED(hr)) {
  82. m_pFaxServer = NULL;
  83. return FALSE;
  84. }
  85. if (!FaxOpenPort( m_pFaxServer->GetFaxHandle(), m_DeviceId, PORT_OPEN_MODIFY | PORT_OPEN_QUERY, &m_FaxPortHandle )) {
  86. if (GetLastError() == ERROR_ACCESS_DENIED) {
  87. if (!FaxOpenPort( m_pFaxServer->GetFaxHandle(), m_DeviceId, PORT_OPEN_QUERY, &m_FaxPortHandle )) {
  88. m_LastFaxError = GetLastError();
  89. return FALSE;
  90. }
  91. } else {
  92. m_LastFaxError = GetLastError();
  93. return FALSE;
  94. }
  95. } else {
  96. m_Modify = TRUE;
  97. }
  98. return TRUE;
  99. }
  100. STDMETHODIMP CFaxPort::get_CanModify(BOOL * pVal)
  101. {
  102. if (!pVal) {
  103. return E_POINTER;
  104. }
  105. __try {
  106. *pVal = m_Modify;
  107. return S_OK;
  108. } __except (EXCEPTION_EXECUTE_HANDLER) {
  109. }
  110. return E_UNEXPECTED;
  111. }
  112. BOOL CFaxPort::ChangePort()
  113. {
  114. if (!m_Modify) {
  115. return FALSE;
  116. }
  117. //
  118. // get the current port configuration
  119. //
  120. PFAX_PORT_INFOW PortInfo = NULL;
  121. DWORD PortInfoSize = 0;
  122. if (!FaxGetPort( m_FaxPortHandle, &PortInfo )) {
  123. m_LastFaxError = GetLastError();
  124. return FALSE;
  125. }
  126. //
  127. // set the values
  128. //
  129. PortInfo->Rings = m_Rings;
  130. PortInfo->Priority = m_Priority;
  131. PortInfo->Flags = (PortInfo->Flags &~ (FPF_SEND | FPF_RECEIVE)) | (m_Send ? FPF_SEND : 0) | (m_Receive ? FPF_RECEIVE : 0);
  132. PortInfo->Csid = m_Csid;
  133. PortInfo->Tsid = m_Tsid;
  134. //
  135. // change the server's port configuration
  136. //
  137. if (!FaxSetPort( m_FaxPortHandle, PortInfo )) {
  138. m_LastFaxError = GetLastError();
  139. FaxFreeBuffer( PortInfo );
  140. return FALSE;
  141. }
  142. //
  143. // clean up and bail
  144. //
  145. FaxFreeBuffer( PortInfo );
  146. return TRUE;
  147. }
  148. STDMETHODIMP CFaxPort::get_Name(BSTR *pVal)
  149. {
  150. if (!pVal) {
  151. return E_POINTER;
  152. }
  153. BSTR Copy = SysAllocString(m_Name);
  154. if (!Copy && m_Name) {
  155. return E_OUTOFMEMORY;
  156. }
  157. __try {
  158. *pVal = Copy;
  159. return S_OK;
  160. } __except (EXCEPTION_EXECUTE_HANDLER) {
  161. SysFreeString(Copy);
  162. }
  163. return E_UNEXPECTED;
  164. }
  165. STDMETHODIMP CFaxPort::get_DeviceId(long * pVal)
  166. {
  167. if (!pVal) {
  168. return E_POINTER;
  169. }
  170. __try {
  171. *pVal = m_DeviceId;
  172. return S_OK;
  173. } __except (EXCEPTION_EXECUTE_HANDLER) {
  174. }
  175. return E_UNEXPECTED;
  176. }
  177. STDMETHODIMP CFaxPort::get_Rings(long * pVal)
  178. {
  179. if (!pVal) {
  180. return E_POINTER;
  181. }
  182. __try {
  183. *pVal = m_Rings;
  184. return S_OK;
  185. } __except (EXCEPTION_EXECUTE_HANDLER) {
  186. }
  187. return E_UNEXPECTED;
  188. }
  189. STDMETHODIMP CFaxPort::put_Rings(long newVal)
  190. {
  191. long old = m_Rings;
  192. if (!m_Modify) {
  193. return E_ACCESSDENIED;
  194. }
  195. m_Rings = newVal;
  196. if (!ChangePort()) {
  197. m_Rings = old;
  198. return Fax_HRESULT_FROM_WIN32(m_LastFaxError);
  199. }
  200. return S_OK;
  201. }
  202. STDMETHODIMP CFaxPort::get_Csid(BSTR * pVal)
  203. {
  204. if (!pVal) {
  205. return E_POINTER;
  206. }
  207. BSTR Copy = SysAllocString(m_Csid);
  208. if (!Copy && m_Csid) {
  209. return E_OUTOFMEMORY;
  210. }
  211. __try {
  212. *pVal = Copy;
  213. return S_OK;
  214. } __except (EXCEPTION_EXECUTE_HANDLER) {
  215. SysFreeString(Copy);
  216. }
  217. return E_UNEXPECTED;
  218. }
  219. STDMETHODIMP CFaxPort::put_Csid(BSTR newVal)
  220. {
  221. BSTR old = m_Csid;
  222. if (!m_Modify) {
  223. return E_ACCESSDENIED;
  224. }
  225. BSTR tmp = SysAllocString(newVal);
  226. if (!tmp && newVal) {
  227. return E_OUTOFMEMORY;
  228. }
  229. m_Csid = tmp;
  230. if (!ChangePort()) {
  231. m_Csid = old;
  232. SysFreeString(tmp);
  233. return Fax_HRESULT_FROM_WIN32(m_LastFaxError);
  234. }
  235. SysFreeString(old);
  236. return S_OK;
  237. }
  238. STDMETHODIMP CFaxPort::get_Tsid(BSTR * pVal)
  239. {
  240. if (!pVal) {
  241. return E_POINTER;
  242. }
  243. BSTR Copy = SysAllocString(m_Tsid);
  244. if (!Copy && m_Tsid) {
  245. return E_OUTOFMEMORY;
  246. }
  247. __try {
  248. *pVal = Copy;
  249. return S_OK;
  250. } __except (EXCEPTION_EXECUTE_HANDLER) {
  251. SysFreeString( m_Csid );
  252. }
  253. return E_UNEXPECTED;
  254. }
  255. STDMETHODIMP CFaxPort::put_Tsid(BSTR newVal)
  256. {
  257. BSTR old = m_Tsid;
  258. if (!m_Modify) {
  259. return E_ACCESSDENIED;
  260. }
  261. BSTR tmp = SysAllocString(newVal);
  262. if (!tmp && newVal) {
  263. return E_OUTOFMEMORY;
  264. }
  265. m_Tsid = tmp;
  266. if (!ChangePort()) {
  267. m_Tsid = old;
  268. SysFreeString(tmp);
  269. return Fax_HRESULT_FROM_WIN32(m_LastFaxError);
  270. }
  271. SysFreeString(old);
  272. return S_OK;
  273. }
  274. STDMETHODIMP CFaxPort::get_Send(BOOL * pVal)
  275. {
  276. if (!pVal) {
  277. return E_POINTER;
  278. }
  279. __try {
  280. *pVal = m_Send;
  281. return S_OK;
  282. } __except (EXCEPTION_EXECUTE_HANDLER) {
  283. }
  284. return E_UNEXPECTED;
  285. }
  286. STDMETHODIMP CFaxPort::put_Send(BOOL newVal)
  287. {
  288. BOOL old = m_Send;
  289. if (!m_Modify) {
  290. return E_ACCESSDENIED;
  291. }
  292. m_Send = newVal;
  293. if (!ChangePort()) {
  294. m_Send = old;
  295. return Fax_HRESULT_FROM_WIN32(m_LastFaxError);
  296. }
  297. return S_OK;
  298. }
  299. STDMETHODIMP CFaxPort::get_Receive(BOOL * pVal)
  300. {
  301. if (!pVal) {
  302. return E_POINTER;
  303. }
  304. __try {
  305. *pVal = m_Receive;
  306. return S_OK;
  307. } __except (EXCEPTION_EXECUTE_HANDLER) {
  308. }
  309. return E_UNEXPECTED;
  310. }
  311. STDMETHODIMP CFaxPort::put_Receive(BOOL newVal)
  312. {
  313. BOOL old = m_Receive;
  314. if (!m_Modify) {
  315. return E_ACCESSDENIED;
  316. }
  317. m_Receive = newVal;
  318. if (!ChangePort()) {
  319. m_Receive = old;
  320. return Fax_HRESULT_FROM_WIN32(m_LastFaxError);
  321. }
  322. return S_OK;
  323. }
  324. STDMETHODIMP CFaxPort::get_Priority(long * pVal)
  325. {
  326. if (!pVal) {
  327. return E_POINTER;
  328. }
  329. __try {
  330. *pVal = m_Priority;
  331. return S_OK;
  332. } __except (EXCEPTION_EXECUTE_HANDLER) {
  333. }
  334. return E_UNEXPECTED;
  335. }
  336. STDMETHODIMP CFaxPort::put_Priority(long newVal)
  337. {
  338. if (newVal < 0)
  339. {
  340. return E_INVALIDARG;
  341. }
  342. long old = m_Priority;
  343. if (!m_Modify) {
  344. return E_ACCESSDENIED;
  345. }
  346. m_Priority = newVal;
  347. if (!ChangePort()) {
  348. m_Priority = old;
  349. return Fax_HRESULT_FROM_WIN32(m_LastFaxError);
  350. }
  351. return S_OK;
  352. }
  353. STDMETHODIMP CFaxPort::GetRoutingMethods(VARIANT * retval)
  354. {
  355. HRESULT hr;
  356. if (!retval) {
  357. return E_POINTER;
  358. }
  359. CComObject<CFaxRoutingMethods>* p = new CComObject<CFaxRoutingMethods>;
  360. if (!p) {
  361. return E_OUTOFMEMORY;
  362. }
  363. if (!p->Init(this)) {
  364. delete p;
  365. return E_FAIL;
  366. }
  367. IDispatch* pDisp;
  368. hr = p->QueryInterface(IID_IDispatch, (void**)&pDisp);
  369. if (FAILED(hr)) {
  370. delete p;
  371. return hr;
  372. }
  373. __try {
  374. VariantInit(retval);
  375. retval->vt = VT_DISPATCH;
  376. retval->pdispVal = pDisp;
  377. return S_OK;
  378. } __except (EXCEPTION_EXECUTE_HANDLER) {
  379. }
  380. pDisp->Release();
  381. delete p;
  382. return E_UNEXPECTED;
  383. }
  384. STDMETHODIMP CFaxPort::GetStatus(VARIANT * retval)
  385. {
  386. HRESULT hr;
  387. if (!retval) {
  388. return E_POINTER;
  389. }
  390. CComObject<CFaxStatus>* p = new CComObject<CFaxStatus>;
  391. if (!p) {
  392. return E_OUTOFMEMORY;
  393. }
  394. if (!p->Init(this)) {
  395. delete p;
  396. return E_FAIL;
  397. }
  398. IDispatch* pDisp;
  399. hr = p->QueryInterface(IID_IDispatch, (void**)&pDisp);
  400. if (FAILED(hr)) {
  401. delete p;
  402. return hr;
  403. }
  404. __try {
  405. VariantInit(retval);
  406. retval->vt = VT_DISPATCH;
  407. retval->pdispVal = pDisp;
  408. return S_OK;
  409. } __except (EXCEPTION_EXECUTE_HANDLER) {
  410. }
  411. pDisp->Release();
  412. delete p;
  413. return E_UNEXPECTED;
  414. }
  415. CFaxPorts::CFaxPorts()
  416. {
  417. m_pFaxServer = NULL;
  418. m_LastFaxError = 0;
  419. m_PortCount = 0;
  420. m_VarVect = NULL;
  421. }
  422. CFaxPorts::~CFaxPorts()
  423. {
  424. if (m_pFaxServer) {
  425. m_pFaxServer->Release();
  426. }
  427. if (m_VarVect) {
  428. delete [] m_VarVect;
  429. }
  430. }
  431. BOOL CFaxPorts::Init(CFaxServer *pFaxServer)
  432. {
  433. PFAX_PORT_INFOW PortInfo = NULL;
  434. DWORD PortInfoSize = 0;
  435. HRESULT hr;
  436. //
  437. // get the ports from the server
  438. //
  439. if (!pFaxServer) {
  440. return FALSE;
  441. }
  442. m_pFaxServer = pFaxServer;
  443. hr = m_pFaxServer->AddRef();
  444. if (FAILED(hr)) {
  445. m_pFaxServer = NULL;
  446. return FALSE;
  447. }
  448. if (!FaxEnumPortsW( m_pFaxServer->GetFaxHandle(), &PortInfo, &m_PortCount )) {
  449. m_LastFaxError = GetLastError();
  450. return FALSE;
  451. }
  452. //
  453. // enumerate the ports
  454. //
  455. m_VarVect = new CComVariant[m_PortCount];
  456. if (!m_VarVect) {
  457. m_LastFaxError = ERROR_OUTOFMEMORY;
  458. FaxFreeBuffer( PortInfo );
  459. return FALSE;
  460. }
  461. for (DWORD i=0; i<m_PortCount; i++)
  462. {
  463. //
  464. // create the object
  465. //
  466. CComObject<CFaxPort> *pFaxPort;
  467. hr = CComObject<CFaxPort>::CreateInstance( &pFaxPort );
  468. if (FAILED(hr))
  469. {
  470. delete [] m_VarVect;
  471. m_VarVect = NULL;
  472. m_LastFaxError = hr;
  473. FaxFreeBuffer( PortInfo );
  474. return FALSE;
  475. }
  476. if (!pFaxPort->Initialize(
  477. pFaxServer,
  478. PortInfo[i].DeviceId,
  479. PortInfo[i].Rings,
  480. PortInfo[i].Priority,
  481. PortInfo[i].Flags,
  482. PortInfo[i].Csid,
  483. PortInfo[i].Tsid,
  484. PortInfo[i].DeviceName
  485. ))
  486. {
  487. delete [] m_VarVect;
  488. m_VarVect = NULL;
  489. m_LastFaxError = GetLastError();
  490. FaxFreeBuffer( PortInfo );
  491. return FALSE;
  492. }
  493. //
  494. // get IDispatch pointer
  495. //
  496. LPDISPATCH lpDisp = NULL;
  497. hr = pFaxPort->QueryInterface( IID_IDispatch, (void**)&lpDisp );
  498. if (FAILED(hr)) {
  499. delete [] m_VarVect;
  500. m_VarVect = NULL;
  501. m_LastFaxError = hr;
  502. FaxFreeBuffer( PortInfo );
  503. return FALSE;
  504. }
  505. //
  506. // create a variant and add it to the collection
  507. //
  508. __try {
  509. CComVariant &var = m_VarVect[i];
  510. var.vt = VT_DISPATCH;
  511. var.pdispVal = lpDisp;
  512. hr = S_OK;
  513. } __except (EXCEPTION_EXECUTE_HANDLER) {
  514. hr = E_UNEXPECTED;
  515. }
  516. if (FAILED(hr)) {
  517. delete [] m_VarVect;
  518. m_VarVect = NULL;
  519. m_LastFaxError = hr;
  520. FaxFreeBuffer( PortInfo );
  521. return FALSE;
  522. }
  523. }
  524. FaxFreeBuffer( PortInfo );
  525. return TRUE;
  526. }
  527. STDMETHODIMP CFaxPorts::get_Count(long * pVal)
  528. {
  529. if (!pVal) {
  530. return E_POINTER;
  531. }
  532. __try {
  533. *pVal = m_PortCount;
  534. return S_OK;
  535. } __except (EXCEPTION_EXECUTE_HANDLER) {
  536. }
  537. return E_UNEXPECTED;
  538. }
  539. STDMETHODIMP CFaxPorts::get_Item(long Index, VARIANT *retval)
  540. {
  541. if (!retval) {
  542. return E_POINTER;
  543. }
  544. if ((Index < 1) || (Index > (long) m_PortCount)) {
  545. return E_INVALIDARG;
  546. }
  547. __try {
  548. VariantInit( retval );
  549. retval->vt = VT_UNKNOWN;
  550. retval->punkVal = NULL;
  551. //
  552. // use 1-based index, VB like
  553. //
  554. return VariantCopy( retval, &m_VarVect[Index-1] );
  555. } __except (EXCEPTION_EXECUTE_HANDLER) {
  556. }
  557. return E_UNEXPECTED;
  558. }