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.

793 lines
17 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : FaxServer.cpp //
  3. // //
  4. // DESCRIPTION : CFaxServer that contains the //
  5. // Connect / Disconnect functionality to the Fax Server //
  6. // //
  7. // //
  8. // AUTHOR : yossg //
  9. // //
  10. // HISTORY : //
  11. // Nov 25 1999 yossg Init . //
  12. // Aug 3 2000 yossg Add notification window //
  13. // //
  14. // Copyright (C) 1999 - 2000 Microsoft Corporation All Rights Reserved //
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "StdAfx.h"
  17. #include "FaxServer.h"
  18. #include "Devices.h"
  19. #include "GeneralNotifyWnd.h"
  20. #include <FaxReg.h>
  21. /*
  22. - CFaxServer::GetFaxServerHandle
  23. -
  24. * Purpose:
  25. * If Handle does not exist re-connect.
  26. * Retreives the Fax Server handle.
  27. *
  28. * Arguments:
  29. *
  30. * Return:
  31. * Fax Server handle, if failed to connect
  32. * retrieves NULL
  33. */
  34. HANDLE CFaxServer::GetFaxServerHandle()
  35. {
  36. if (!m_hFaxHandle)
  37. {
  38. ATLASSERT (!m_hDevicesStatusNotification);
  39. HRESULT hRc = Connect();
  40. if ( FAILED(hRc))
  41. {
  42. // DebugPrintEx(DEBUG_ERR)
  43. // should been already given by
  44. // this function caller.
  45. }
  46. }
  47. return m_hFaxHandle;
  48. }
  49. /*
  50. - CFaxServer::Connect
  51. -
  52. * Purpose:
  53. * Connect to the Fax Server.
  54. *
  55. * Arguments:
  56. *
  57. * Return:
  58. *
  59. */
  60. HRESULT CFaxServer::Connect()
  61. {
  62. DEBUG_FUNCTION_NAME(TEXT("CFaxServer::Connect"));
  63. DWORD ec = ERROR_SUCCESS;
  64. ATLASSERT(!m_hFaxHandle);
  65. //
  66. // Connect to server
  67. //
  68. if (!FaxConnectFaxServer (m_bstrServerName, &m_hFaxHandle))
  69. {
  70. ec= GetLastError();
  71. DebugPrintEx(
  72. DEBUG_ERR,
  73. _T("FaxConnectFaxServer() Failed to %ws. (ec: %ld)"),
  74. ((!m_bstrServerName) || (m_bstrServerName == L""))? L"local machine" : m_bstrServerName.m_str,
  75. ec);
  76. m_hFaxHandle = NULL;
  77. return HRESULT_FROM_WIN32(ec);
  78. }
  79. ATLASSERT(m_hFaxHandle);
  80. //
  81. // Check Server API Version
  82. //
  83. if(!FaxGetReportedServerAPIVersion(m_hFaxHandle, &m_dwServerAPIVersion))
  84. {
  85. //
  86. // Cannot retrieve version info
  87. //
  88. ec= GetLastError();
  89. DebugPrintEx(DEBUG_ERR, _T("FaxGetReportedServerAPIVersion() failed with %ld)"), ec);
  90. Disconnect();
  91. return HRESULT_FROM_WIN32(ec);
  92. }
  93. if(m_dwServerAPIVersion > CURRENT_FAX_API_VERSION)
  94. {
  95. //
  96. // Cannot manage later version of fax
  97. //
  98. Disconnect();
  99. return HRESULT_FROM_WIN32(ERROR_RMODE_APP);
  100. }
  101. PRODUCT_SKU_TYPE ServerSKU = PRODUCT_SKU_UNKNOWN;
  102. if(!FaxGetServerSKU(m_hFaxHandle, &ServerSKU))
  103. {
  104. ec = GetLastError();
  105. DebugPrintEx(DEBUG_ERR, _T("FaxGetServerSKU() failed with %ld)"), ec);
  106. Disconnect();
  107. return HRESULT_FROM_WIN32(ec);
  108. }
  109. if(IsDesktopSKUFromSKU(ServerSKU))
  110. {
  111. //
  112. // We are connected to WinXP Desktop SKU
  113. // It cannot be managed remotely
  114. //
  115. m_bDesktopSKUConnection = TRUE;
  116. Disconnect();
  117. return HRESULT_FROM_WIN32(ERROR_RMODE_APP);
  118. }
  119. //
  120. // Verify or re-establish (if needed) notification setup
  121. //
  122. if (m_pDevicesNode)
  123. {
  124. HRESULT hRc = InternalRegisterForDeviceNotifications();
  125. if (S_OK != hRc)
  126. {
  127. DebugPrintEx(
  128. DEBUG_ERR,
  129. _T("InternalRegisterForDeviceNotifications Failed. (hRc: %08X)"),
  130. hRc);
  131. }
  132. }
  133. DebugPrintEx(
  134. DEBUG_MSG,
  135. _T("FaxConnectFaxServer() succeeded. Handle: %08X"),
  136. m_hFaxHandle);
  137. return S_OK;
  138. }
  139. /*
  140. - CFaxServer::Disconnect
  141. -
  142. * Purpose:
  143. * Disconnect from the Fax Server.
  144. *
  145. * Arguments:
  146. *
  147. * Return:
  148. *
  149. */
  150. HRESULT CFaxServer::Disconnect()
  151. {
  152. DEBUG_FUNCTION_NAME(TEXT("CFaxServer::Disconnect"));
  153. HRESULT hRc = S_OK;
  154. DWORD ec;
  155. if (NULL == m_hFaxHandle)
  156. {
  157. hRc = E_FAIL;
  158. DebugPrintEx(
  159. DEBUG_MSG,
  160. _T("No connection handle exists. (m_hFaxHandle is NULL)\n Connection may not started or disconnected before.\n "));
  161. return hRc;
  162. }
  163. hRc = UnRegisterForNotifications();
  164. if (S_OK != hRc)
  165. {
  166. DebugPrintEx(
  167. DEBUG_ERR,
  168. _T("UnRegisterForNotifications() failed. (hRc: %0X8)"),
  169. hRc);
  170. // continue!!!
  171. }
  172. if (!FaxClose (m_hFaxHandle))
  173. {
  174. ec= GetLastError();
  175. DebugPrintEx(
  176. DEBUG_ERR,
  177. _T("FaxClose() failed. (ec: %ld)"),
  178. ec);
  179. hRc = HRESULT_FROM_WIN32(ec);
  180. goto Cleanup;
  181. }
  182. DebugPrintEx( DEBUG_MSG,
  183. _T("Succeeded to close connection to Fax. ServerHandle: %08X"),
  184. m_hFaxHandle);
  185. Cleanup:
  186. m_hFaxHandle = NULL;
  187. return hRc;
  188. }
  189. /*
  190. - CFaxServer::SetServerName
  191. -
  192. * Purpose:
  193. * Set the Server machine name
  194. *
  195. * Arguments:
  196. *
  197. * Return:
  198. * OLE error code
  199. */
  200. HRESULT CFaxServer::SetServerName(BSTR bstrServerName)
  201. {
  202. DEBUG_FUNCTION_NAME( _T("CFaxServer::SetServerName"));
  203. HRESULT hRc = S_OK;
  204. m_bstrServerName = bstrServerName;
  205. if (!m_bstrServerName)
  206. {
  207. hRc = E_OUTOFMEMORY;
  208. DebugPrintEx(
  209. DEBUG_ERR,
  210. _T("Failed to allocate string - out of memory"));
  211. m_bstrServerName = L"";
  212. }
  213. return hRc;
  214. }
  215. /*
  216. - CFaxServer::GetServerName
  217. -
  218. * Purpose:
  219. * Set the Server machine name
  220. *
  221. * Arguments:
  222. *
  223. * Return:
  224. * OLE error code
  225. */
  226. const CComBSTR& CFaxServer::GetServerName()
  227. {
  228. DEBUG_FUNCTION_NAME( _T("CFaxServer::GetServerName"));
  229. return m_bstrServerName;
  230. }
  231. /*
  232. +
  233. +
  234. * CFaxServer::IsServerRunningFaxService
  235. *
  236. * Purpose:
  237. * Contacts the machine and determines if Fax Server Service is running.
  238. *
  239. * Arguments:
  240. *
  241. * Return:
  242. * boolean value Running or notruning
  243. -
  244. -
  245. */
  246. BOOL CFaxServer::IsServerRunningFaxService ( )
  247. {
  248. DEBUG_FUNCTION_NAME( _T("CFaxServer::IsServerRunningFaxService"));
  249. SC_HANDLE SCMHandle = NULL;
  250. SC_HANDLE FXSHandle = NULL;
  251. SERVICE_STATUS SStatus;
  252. BOOL bRun = FALSE;
  253. if (
  254. (SCMHandle = OpenSCManager(m_bstrServerName, NULL, GENERIC_READ))
  255. &&
  256. (FXSHandle = OpenService(SCMHandle, FAX_SERVICE_NAME, SERVICE_QUERY_STATUS))
  257. &&
  258. QueryServiceStatus(FXSHandle, &SStatus)
  259. &&
  260. (SERVICE_RUNNING == SStatus.dwCurrentState)
  261. )
  262. {
  263. bRun = TRUE;
  264. }
  265. if (FXSHandle)
  266. {
  267. CloseServiceHandle(FXSHandle);
  268. }
  269. else // FXSHandle == NULL
  270. {
  271. DebugPrintEx(
  272. DEBUG_ERR,
  273. _T("Fail to Open Fax Server Service. (ec: %ld)"),
  274. GetLastError());
  275. }
  276. if (SCMHandle)
  277. {
  278. CloseServiceHandle(SCMHandle);
  279. }
  280. else // SCMHandle == NULL
  281. {
  282. DebugPrintEx(
  283. DEBUG_ERR,
  284. _T("Fail to OpenSCManager. (ec: %ld)"),
  285. GetLastError());
  286. }
  287. return bRun;
  288. }
  289. /*
  290. +
  291. +
  292. * CFaxServer::IsServerFaxServiceStopped
  293. *
  294. * Purpose:
  295. * Contacts the machine and determines if Fax Server Service is already stopped.
  296. *
  297. * Arguments:
  298. * [in] bstrServerName - the server name
  299. *
  300. * Return:
  301. * boolean value Running or notruning
  302. -
  303. -
  304. */
  305. BOOL CFaxServer::IsServerFaxServiceStopped( )
  306. {
  307. DEBUG_FUNCTION_NAME( _T("CFaxServer::IsServerFaxServiceStopped"));
  308. SC_HANDLE SCMHandle = NULL;
  309. SC_HANDLE FXSHandle = NULL;
  310. SERVICE_STATUS SStatus;
  311. BOOL bRun = FALSE;
  312. if (
  313. (SCMHandle = OpenSCManager(m_bstrServerName, NULL, GENERIC_READ))
  314. &&
  315. (FXSHandle = OpenService(SCMHandle, FAX_SERVICE_NAME, SERVICE_QUERY_STATUS))
  316. &&
  317. QueryServiceStatus(FXSHandle, &SStatus)
  318. &&
  319. (SERVICE_STOPPED == SStatus.dwCurrentState)
  320. )
  321. {
  322. bRun = TRUE;
  323. }
  324. if (FXSHandle)
  325. {
  326. CloseServiceHandle(FXSHandle);
  327. }
  328. else // FXSHandle == NULL
  329. {
  330. DebugPrintEx(
  331. DEBUG_ERR,
  332. _T("Fail to Open Fax Server Service. (ec: %ld)"),
  333. GetLastError());
  334. }
  335. if (SCMHandle)
  336. {
  337. CloseServiceHandle(SCMHandle);
  338. }
  339. else // SCMHandle == NULL
  340. {
  341. DebugPrintEx(
  342. DEBUG_ERR,
  343. _T("Fail to OpenSCManager. (ec: %ld)"),
  344. GetLastError());
  345. }
  346. return bRun;
  347. }
  348. /*
  349. +
  350. +
  351. * CFaxServer::CreateNotifyWindow
  352. *
  353. * Purpose:
  354. * Init notification window
  355. *
  356. * Arguments:
  357. *
  358. * Return:
  359. * OLE error code
  360. -
  361. -
  362. */
  363. DWORD CFaxServer::CreateNotifyWindow( )
  364. {
  365. DEBUG_FUNCTION_NAME( _T("CFaxServer::CreateNotifyWindow"));
  366. DWORD ec = ERROR_SUCCESS;
  367. RECT rcRect;
  368. ZeroMemory(&rcRect, sizeof(rcRect));
  369. HWND hDevicesNotifyHandle;
  370. ATLASSERT(!m_pNotifyWin);
  371. m_pNotifyWin = new CFaxGeneralNotifyWnd(this);
  372. if (!m_pNotifyWin)
  373. {
  374. ec = ERROR_NOT_ENOUGH_MEMORY;
  375. SetLastError(ec);
  376. DebugPrintEx(
  377. DEBUG_ERR,
  378. TEXT("Fail to create CFaxGeneralNotifyWnd - Out of memory."));
  379. goto Exit;
  380. }
  381. hDevicesNotifyHandle = m_pNotifyWin->Create(NULL,
  382. rcRect,
  383. NULL, //LPCTSTR szWindowName
  384. WS_POPUP, //DWORD dwStyle
  385. 0x0,
  386. 0);
  387. ATLASSERT(m_pNotifyWin->m_hWnd == m_hDevicesNotifyHandle);
  388. if (!(::IsWindow(hDevicesNotifyHandle)))
  389. {
  390. ec = ERROR_INVALID_HANDLE;
  391. DebugPrintEx(
  392. DEBUG_ERR,
  393. _T("Failed to create window."));
  394. hDevicesNotifyHandle = NULL;
  395. delete m_pNotifyWin;
  396. m_pNotifyWin = NULL;
  397. goto Exit;
  398. }
  399. ATLASSERT(ERROR_SUCCESS == ec);
  400. goto Exit;
  401. Exit:
  402. return ec;
  403. }
  404. /*
  405. +
  406. +
  407. * CFaxServer::UnRegisterForNotifications
  408. *
  409. * Purpose:
  410. * UnRegisterFor Server Event Notifications
  411. *
  412. * Arguments:
  413. *
  414. * Return:
  415. * OLE error code
  416. -
  417. -
  418. */
  419. HRESULT CFaxServer::UnRegisterForNotifications()
  420. {
  421. DEBUG_FUNCTION_NAME( _T("CFaxServer::UnRegisterForNotifications"));
  422. DWORD ec = ERROR_SUCCESS;
  423. if (m_hDevicesStatusNotification)
  424. {
  425. //
  426. // Unregister server notifications
  427. //
  428. if (!FaxUnregisterForServerEvents (m_hDevicesStatusNotification))
  429. {
  430. ec = GetLastError ();
  431. DebugPrintEx(
  432. DEBUG_ERR,
  433. _T("Fail to Unregister For Device status Server Events. (ec: %ld)"),
  434. ec);
  435. m_hDevicesStatusNotification = NULL;
  436. goto Exit;
  437. }
  438. }
  439. Exit:
  440. return HRESULT_FROM_WIN32(ec);
  441. }
  442. /*
  443. +
  444. +
  445. * CFaxServer::RegisterForNotification
  446. *
  447. * Purpose:
  448. * RegisterFor Server Event Notifications
  449. *
  450. * Arguments:
  451. *
  452. * Return:
  453. * OLE error code
  454. -
  455. -
  456. */
  457. DWORD CFaxServer::RegisterForNotifications()
  458. {
  459. DEBUG_FUNCTION_NAME( _T("CFaxServer::RegisterForNotifications"));
  460. DWORD ec = ERROR_SUCCESS;
  461. //
  462. // Register for device status notification
  463. //
  464. ATLASSERT(!m_hDevicesStatusNotification);
  465. ATLASSERT(m_pNotifyWin);
  466. ATLASSERT(m_pNotifyWin->IsWindow());
  467. if (!FaxRegisterForServerEvents (
  468. m_hFaxHandle,
  469. FAX_EVENT_TYPE_DEVICE_STATUS,
  470. NULL,
  471. 0,
  472. m_pNotifyWin->m_hWnd,
  473. WM_GENERAL_EVENT_NOTIFICATION,
  474. &m_hDevicesStatusNotification
  475. )
  476. )
  477. {
  478. ec = GetLastError();
  479. DebugPrintEx(
  480. DEBUG_ERR,
  481. _T("Fail to Register For Device Status Server Events (ec: %ld)"), ec);
  482. m_hDevicesStatusNotification = NULL;
  483. goto Exit;
  484. }
  485. ATLASSERT(m_hDevicesStatusNotification);
  486. Exit:
  487. return ec;
  488. }
  489. /*
  490. +
  491. +
  492. * CFaxServer::InternalRegisterForDeviceNotifications
  493. *
  494. * Purpose:
  495. * Call the members to create window and register for device notifications
  496. *
  497. * Arguments:
  498. * non.
  499. *
  500. * Return:
  501. * HRESULT
  502. -
  503. -
  504. */
  505. HRESULT CFaxServer::InternalRegisterForDeviceNotifications()
  506. {
  507. DEBUG_FUNCTION_NAME( _T("CFaxServer::InternalRegisterForDeviceNotifications"));
  508. DWORD ec = ERROR_SUCCESS;
  509. ATLASSERT (m_pDevicesNode);
  510. //
  511. // Check/Create notification window
  512. //
  513. if (!m_pNotifyWin)
  514. {
  515. ATLASSERT(!m_hDevicesStatusNotification);
  516. ec = CreateNotifyWindow();
  517. if ( ERROR_SUCCESS != ec)
  518. {
  519. DebugPrintEx(
  520. DEBUG_MSG,
  521. _T("Fail to CreateNotifyWindow(). (ec: %ld)"),
  522. ec);
  523. return HRESULT_FROM_WIN32(ec);
  524. }
  525. }
  526. ATLASSERT(m_pNotifyWin);
  527. //
  528. // Check/register to event notification
  529. //
  530. if (!m_hDevicesStatusNotification)
  531. {
  532. ec = RegisterForNotifications();
  533. if (ERROR_SUCCESS != ec)
  534. {
  535. DebugPrintEx(
  536. DEBUG_ERR,
  537. _T("Fail to RegisterForNotification()"),
  538. ec);
  539. ATLASSERT(!m_hDevicesStatusNotification);
  540. //
  541. // Keep the notification window alive.
  542. // Try next time to register only.
  543. //
  544. return HRESULT_FROM_WIN32(ec);
  545. }
  546. ATLASSERT(m_hDevicesStatusNotification);
  547. }
  548. return S_OK;
  549. }
  550. /*
  551. +
  552. +
  553. * CFaxServer::OnNewEvent
  554. *
  555. * Purpose:
  556. * Called when new registered event reaches window
  557. *
  558. * Arguments:
  559. * pFaxEvent [in] - PFAX_EVENT_EX structure pointer
  560. *
  561. * Return:
  562. * OLE error code
  563. -
  564. -
  565. */
  566. HRESULT CFaxServer::OnNewEvent(PFAX_EVENT_EX pFaxEvent)
  567. {
  568. DEBUG_FUNCTION_NAME( _T("CFaxServer::OnNewEvent"));
  569. HRESULT hRc = S_OK;
  570. //
  571. // Update "Devices" Node
  572. //
  573. if ( FAX_EVENT_TYPE_DEVICE_STATUS == pFaxEvent->EventType )
  574. {
  575. ATLASSERT( m_pDevicesNode);
  576. hRc = m_pDevicesNode->UpdateDeviceStatusChange(
  577. pFaxEvent->EventInfo.DeviceStatus.dwDeviceId,
  578. pFaxEvent->EventInfo.DeviceStatus.dwNewStatus);
  579. if (S_OK != hRc)
  580. {
  581. DebugPrintEx(
  582. DEBUG_ERR,
  583. _T("Failed to UpdateDeviceStatusChange()"));
  584. goto Exit;
  585. }
  586. }
  587. else
  588. {
  589. ATLASSERT(FALSE); //Unsupported EVENT
  590. }
  591. Exit:
  592. return hRc;
  593. }
  594. /*
  595. +
  596. +
  597. * CFaxServer::RegisterForDeviceNotifications
  598. *
  599. * Purpose:
  600. * Init Devices notification window
  601. *
  602. * Arguments:
  603. * pDevices [in] - pointer to "devices" node
  604. *
  605. * Return:
  606. * OLE error code
  607. -
  608. -
  609. */
  610. HRESULT CFaxServer::RegisterForDeviceNotifications(CFaxDevicesNode * pDevices)
  611. {
  612. DEBUG_FUNCTION_NAME( _T("CFaxServer::RegisterForDeviceNotifications"));
  613. HRESULT hRc = S_OK;
  614. //
  615. // Set pointer to Devices node
  616. //
  617. m_pDevicesNode = pDevices;
  618. ATLASSERT (m_pDevicesNode);
  619. //
  620. // Now try to do the stages needed for this registration to happen
  621. //
  622. hRc = InternalRegisterForDeviceNotifications();
  623. if (S_OK != hRc)
  624. {
  625. DebugPrintEx(
  626. DEBUG_ERR,
  627. _T("InternalRegisterForDeviceNotifications Failed. (hRc: %08X)"),
  628. hRc);
  629. }
  630. return hRc;
  631. }
  632. /*
  633. +
  634. +
  635. * CFaxServer::DestroyNotifyWindow
  636. *
  637. * Purpose:
  638. * DestroyNotifyWindow
  639. *
  640. * Arguments:
  641. *
  642. * Return:
  643. * VOID
  644. -
  645. -
  646. */
  647. VOID CFaxServer::DestroyNotifyWindow()
  648. {
  649. DEBUG_FUNCTION_NAME( _T("CFaxServer::DestroyNotifyWindow"));
  650. //
  651. // Destroy Notification Window
  652. //
  653. if (NULL != m_pNotifyWin)
  654. {
  655. if (m_pNotifyWin->IsWindow())
  656. {
  657. m_pNotifyWin->DestroyWindow();
  658. }
  659. delete m_pNotifyWin;
  660. m_pNotifyWin = NULL;
  661. }
  662. return;
  663. }