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.

1459 lines
35 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : Device.cpp //
  3. // //
  4. // DESCRIPTION : Fax Server MMC node creation. //
  5. // //
  6. // AUTHOR : yossg //
  7. // //
  8. // HISTORY : //
  9. // Sep 22 1999 yossg Create //
  10. // Dec 1 1999 yossg Change totaly for new mockup version 0.7 //
  11. // Dec 6 1999 yossg add FaxChangeState functionality //
  12. // Dec 12 1999 yossg add OnPropertyChange functionality //
  13. // Aug 3 2000 yossg Add Device status real-time notification //
  14. // Oct 17 2000 yossg //
  15. // Windows XP //
  16. // Feb 14 2001 yossg Add Manual Receive support //
  17. // //
  18. // Copyright (C) 1999 - 2000 Microsoft Corporation All Rights Reserved //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "StdAfx.h"
  21. #include <FaxMMC.h>
  22. #include "Device.h"
  23. #include "Devices.h"
  24. #include "FaxServer.h"
  25. #include "FaxServerNode.h"
  26. #include "ppFaxDeviceGeneral.h"
  27. #include "InboundRoutingMethods.h"
  28. #include "FaxMMCPropertyChange.h"
  29. #include "Icons.h"
  30. #include "oaidl.h"
  31. //Old Num (also in comet) C0548D62-1B45-11d3-B8C0-00104B3FF735
  32. /////////////////////////////////////////////////////////////////////////////
  33. // {3115A19A-6251-46ac-9425-14782858B8C9}
  34. static const GUID CFaxDeviceNodeGUID_NODETYPE = FAXSRV_DEVICE_NODETYPE_GUID;
  35. const GUID* CFaxDeviceNode::m_NODETYPE = &CFaxDeviceNodeGUID_NODETYPE;
  36. const OLECHAR* CFaxDeviceNode::m_SZNODETYPE = FAXSRV_DEVICE_NODETYPE_GUID_STR;
  37. const CLSID* CFaxDeviceNode::m_SNAPIN_CLASSID = &CLSID_Snapin;
  38. CColumnsInfo CFaxDeviceNode::m_ColsInfo;
  39. CLIPFORMAT CFaxDeviceNode::m_CFPermanentDeviceID =
  40. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_DEVICE_ID);
  41. CLIPFORMAT CFaxDeviceNode::m_CFFspGuid =
  42. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_FSP_GUID);
  43. CLIPFORMAT CFaxDeviceNode::m_CFServerName =
  44. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_SERVER_NAME);
  45. DWORD CFaxDeviceNode::GetDeviceID()
  46. {
  47. return m_dwDeviceID;
  48. }
  49. /*
  50. - CFaxDeviceNode::InsertColumns
  51. -
  52. * Purpose:
  53. * Adds columns to the default result pane.
  54. *
  55. * Arguments:
  56. * [in] pHeaderCtrl - IHeaderCtrl in the console-provided default result view pane
  57. *
  58. * Return:
  59. * OLE error code
  60. */
  61. HRESULT
  62. CFaxDeviceNode::InsertColumns(IHeaderCtrl *pHeaderCtrl)
  63. {
  64. SCODE hRc;
  65. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::InsertColumns"));
  66. static ColumnsInfoInitData ColumnsInitData[] =
  67. {
  68. {IDS_FAX_COL_HEAD, FXS_WIDE_COLUMN_WIDTH},
  69. {LAST_IDS, 0}
  70. };
  71. hRc = m_ColsInfo.InsertColumnsIntoMMC(pHeaderCtrl,
  72. _Module.GetResourceInstance(),
  73. ColumnsInitData);
  74. if (hRc != S_OK)
  75. {
  76. DebugPrintEx(DEBUG_ERR,
  77. _T("m_ColsInfo.InsertColumnsIntoMMC"));
  78. goto Cleanup;
  79. }
  80. Cleanup:
  81. return(hRc);
  82. }
  83. /*
  84. - CFaxDeviceNode::PopulateScopeChildrenList
  85. -
  86. * Purpose:
  87. * Create the Fax Device Inbound Routing Methods node
  88. *
  89. * Arguments:
  90. *
  91. * Return:
  92. * OLE error code
  93. * Actually it is the last OLE error code that ocoured
  94. * during processing this method.
  95. */
  96. HRESULT CFaxDeviceNode::PopulateScopeChildrenList()
  97. {
  98. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::PopulateScopeChildrenList"));
  99. HRESULT hRc = S_OK;
  100. CFaxInboundRoutingMethodsNode * pMethods = NULL;
  101. //
  102. // Prepare IConsoleNameSpace for case of failure
  103. //
  104. ATLASSERT(m_pComponentData);
  105. ATLASSERT( ((CSnapin*)m_pComponentData)->m_spConsole );
  106. CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace( ((CSnapin*)m_pComponentData)->m_spConsole );
  107. ATLASSERT( spConsoleNameSpace );
  108. //
  109. // Fax InboundRoutingMethods Node
  110. //
  111. pMethods = new CFaxInboundRoutingMethodsNode(this, m_pComponentData);
  112. if (!pMethods)
  113. {
  114. hRc = E_OUTOFMEMORY;
  115. NodeMsgBox(IDS_MEMORY);
  116. DebugPrintEx(
  117. DEBUG_ERR,
  118. TEXT("Out of memory. (hRc: %08X)"),
  119. hRc);
  120. goto Error;
  121. }
  122. else
  123. {
  124. pMethods->InitParentNode(this);
  125. pMethods->SetIcons(IMAGE_METHOD_ENABLE, IMAGE_METHOD_ENABLE);
  126. hRc = pMethods->InitDisplayName();
  127. if ( FAILED(hRc) )
  128. {
  129. DebugPrintEx(DEBUG_ERR,_T("Failed to display node name. (hRc: %08X)"), hRc);
  130. NodeMsgBox(IDS_FAILTOADD_METHODS);
  131. goto Error;
  132. }
  133. hRc = AddChild(pMethods, &pMethods->m_scopeDataItem);
  134. if (FAILED(hRc))
  135. {
  136. DebugPrintEx(
  137. DEBUG_ERR,
  138. TEXT("Fail to add the methods node. (hRc: %08X)"),
  139. hRc);
  140. NodeMsgBox(IDS_FAILTOADD_METHODS);
  141. goto Error;
  142. }
  143. }
  144. ATLASSERT(S_OK == hRc);
  145. goto Exit;
  146. Error:
  147. ATLASSERT(S_OK != hRc);
  148. if ( NULL != pMethods )
  149. {
  150. if (0 != pMethods->m_scopeDataItem.ID )
  151. {
  152. HRESULT hr = spConsoleNameSpace->DeleteItem(pMethods->m_scopeDataItem.ID, TRUE);
  153. if (hr != S_OK) // can be only E_UNEXPECTED [MSDN]
  154. {
  155. DebugPrintEx(
  156. DEBUG_ERR,
  157. TEXT("spConsoleNameSpace->DeleteItem() Failed - Unexpected error. (hRc: %08X)"),
  158. hr);
  159. ATLASSERT(FALSE);
  160. }
  161. }
  162. delete pMethods;
  163. pMethods = NULL;
  164. }
  165. // Empty the list of all Devices added before the one who failed
  166. m_ScopeChildrenList.RemoveAll();
  167. m_bScopeChildrenListPopulated = FALSE;
  168. Exit:
  169. return hRc;
  170. }
  171. /*
  172. - CFaxDeviceNode::GetResultPaneColInfo
  173. -
  174. * Purpose:
  175. * Return the text for specific column
  176. * Called for each column in the result pane
  177. *
  178. * Arguments:
  179. * [in] nCol - column number
  180. *
  181. * Return:
  182. * String to be displayed in the specific column
  183. */
  184. LPOLESTR CFaxDeviceNode::GetResultPaneColInfo(int nCol)
  185. {
  186. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::GetResultPaneColInfo"));
  187. HRESULT hRc = S_OK;
  188. int iCount;
  189. WCHAR buff[FXS_MAX_RINGS_LEN+1];
  190. UINT uiResourceId = 0;
  191. m_buf.Empty();
  192. switch (nCol)
  193. {
  194. case 0:
  195. //
  196. // Name
  197. //
  198. if (!m_bstrDisplayName)
  199. {
  200. DebugPrintEx(
  201. DEBUG_ERR,
  202. TEXT("Null memeber BSTR - m_bstrDisplayName."));
  203. goto Error;
  204. }
  205. else
  206. {
  207. return (m_bstrDisplayName);
  208. }
  209. break;
  210. case 1:
  211. //
  212. // Receive
  213. //
  214. if (m_fManualReceive)
  215. {
  216. uiResourceId = IDS_DEVICE_MANUAL;
  217. }
  218. else
  219. {
  220. uiResourceId = (m_fAutoReceive ? IDS_DEVICE_AUTO : IDS_FXS_NO);
  221. }
  222. if (!m_buf.LoadString(_Module.GetResourceInstance(), uiResourceId) )
  223. {
  224. DebugPrintEx(
  225. DEBUG_ERR,
  226. TEXT("Fail to load string for receive value."));
  227. goto Error;
  228. }
  229. else
  230. {
  231. return (m_buf);
  232. }
  233. break;
  234. case 2:
  235. //
  236. // Send
  237. //
  238. uiResourceId = (m_fSend ? IDS_FXS_YES : IDS_FXS_NO);
  239. if (!m_buf.LoadString(_Module.GetResourceInstance(), uiResourceId) )
  240. {
  241. DebugPrintEx(
  242. DEBUG_ERR,
  243. TEXT("Fail to load string for send value."));
  244. goto Error;
  245. }
  246. else
  247. {
  248. return (m_buf);
  249. }
  250. break;
  251. case 3:
  252. //
  253. // Status
  254. // Although the FAX_DEVICE_STATUS_* constants are defined as bitmasks,
  255. // in this release there cannot be any combination of bits.
  256. //
  257. switch (m_dwStatus)
  258. {
  259. case FAX_DEVICE_STATUS_RINGING:
  260. uiResourceId = IDS_DEVICE_STATUS_RINGING;
  261. break;
  262. case FAX_DEVICE_STATUS_SENDING:
  263. uiResourceId = IDS_DEVICE_STATUS_SENDING;
  264. break;
  265. case FAX_DEVICE_STATUS_RECEIVING:
  266. uiResourceId = IDS_DEVICE_STATUS_RECEIVING;
  267. break;
  268. case FAX_DEVICE_STATUS_POWERED_OFF:
  269. uiResourceId = IDS_DEVICE_STATUS_POWERED_OFF;
  270. break;
  271. default:
  272. //
  273. // All other combinations are mapped to 'idle'
  274. //
  275. uiResourceId = IDS_DEVICE_STATUS_IDLE;
  276. break;
  277. }
  278. if (!m_buf.LoadString(_Module.GetResourceInstance(), uiResourceId) )
  279. {
  280. DebugPrintEx(
  281. DEBUG_ERR,
  282. TEXT("Fail to load string for receive value."));
  283. goto Error;
  284. }
  285. else
  286. {
  287. return (m_buf);
  288. }
  289. break;
  290. case 4:
  291. //
  292. // Rings
  293. //
  294. iCount = swprintf(buff, L"%ld", m_dwRings);
  295. if( iCount <= 0 )
  296. {
  297. DebugPrintEx(
  298. DEBUG_ERR,
  299. TEXT("Fail to read member - m_dwRings."));
  300. goto Error;
  301. }
  302. else
  303. {
  304. m_buf = buff;
  305. return (m_buf);
  306. }
  307. break;
  308. case 5:
  309. //
  310. // Provider
  311. //
  312. if (!m_bstrProviderName)
  313. {
  314. DebugPrintEx(
  315. DEBUG_ERR,
  316. TEXT("Null memeber BSTR - m_bstrProviderName."));
  317. goto Error;
  318. }
  319. else
  320. {
  321. return (m_bstrProviderName);
  322. }
  323. break;
  324. case 6:
  325. //
  326. // Description
  327. //
  328. if (!m_bstrDescription)
  329. {
  330. DebugPrintEx(
  331. DEBUG_ERR,
  332. TEXT("Null memeber BSTR - m_bstrDescription."));
  333. goto Error;
  334. }
  335. else
  336. {
  337. return (m_bstrDescription);
  338. }
  339. break;
  340. default:
  341. ATLASSERT(0); // "this number of column is not supported "
  342. return(L"");
  343. } // endswitch (nCol)
  344. Error:
  345. return(L"???");
  346. }
  347. /*
  348. - CFaxDeviceNode::CreatePropertyPages
  349. -
  350. * Purpose:
  351. * Called when creating a property page of the object
  352. *
  353. * Arguments:
  354. * [in] lpProvider - The property sheet
  355. * [in] handle - Handle for notification
  356. * [in] pUnk - Pointer to the data object
  357. * [in] type - CCT_* (SCOPE, RESULT, ...)
  358. *
  359. * Return:
  360. * OLE error code
  361. */
  362. HRESULT
  363. CFaxDeviceNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  364. LONG_PTR handle,
  365. IUnknown *pUnk,
  366. DATA_OBJECT_TYPES type)
  367. {
  368. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::CreatePropertyPages"));
  369. HRESULT hRc = S_OK;
  370. ATLASSERT(lpProvider);
  371. ATLASSERT(type == CCT_RESULT || type == CCT_SCOPE);
  372. m_pFaxDeviceGeneral = NULL;
  373. //
  374. // General
  375. //
  376. m_pFaxDeviceGeneral = new CppFaxDeviceGeneral(
  377. handle,
  378. this,
  379. m_pParentNode,
  380. m_dwDeviceID,
  381. _Module.GetResourceInstance());
  382. if (!m_pFaxDeviceGeneral)
  383. {
  384. hRc = E_OUTOFMEMORY;
  385. NodeMsgBox(IDS_MEMORY_FAIL_TO_OPEN_PP);
  386. goto Error;
  387. }
  388. hRc = m_pFaxDeviceGeneral->InitRPC();
  389. if (FAILED(hRc))
  390. {
  391. DebugPrintEx(
  392. DEBUG_ERR,
  393. TEXT("Fail to call RPC to init property page for the General tab. (hRc: %08X)"),
  394. hRc);
  395. goto Error;
  396. }
  397. hRc = lpProvider->AddPage(m_pFaxDeviceGeneral->Create());
  398. if (FAILED(hRc))
  399. {
  400. DebugPrintEx(
  401. DEBUG_ERR,
  402. TEXT("Fail to add property page for General Tab. (hRc: %08X)"),
  403. hRc);
  404. NodeMsgBox(IDS_FAIL_TO_OPEN_PROP_PAGE);
  405. goto Error;
  406. }
  407. ATLASSERT(S_OK == hRc);
  408. goto Exit;
  409. Error:
  410. ATLASSERT(S_OK != hRc);
  411. if ( NULL != m_pFaxDeviceGeneral )
  412. {
  413. delete m_pFaxDeviceGeneral;
  414. m_pFaxDeviceGeneral = NULL;
  415. }
  416. Exit:
  417. return hRc;
  418. }
  419. /*
  420. - CFaxDeviceNode::SetVerbs
  421. -
  422. * Purpose:
  423. * What verbs to enable/disable when this object is selected
  424. *
  425. * Arguments:
  426. * [in] pConsoleVerb - MMC ConsoleVerb interface
  427. *
  428. * Return:
  429. * OLE Error code
  430. */
  431. HRESULT CFaxDeviceNode::SetVerbs(IConsoleVerb *pConsoleVerb)
  432. {
  433. HRESULT hRc = S_OK;
  434. //
  435. // Display verbs that we support:
  436. // 1. Properties
  437. //
  438. hRc = pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
  439. //
  440. // We want the default verb to be Properties
  441. //
  442. hRc = pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  443. return hRc;
  444. }
  445. /*
  446. - CFaxDeviceNode::InitRPC
  447. -
  448. * Purpose:
  449. * Initiates the configuration structure from RPC get Call.
  450. *
  451. * Arguments:
  452. *
  453. * Return:
  454. * OLE error code
  455. */
  456. HRESULT CFaxDeviceNode::InitRPC( PFAX_PORT_INFO_EX * pFaxDeviceConfig )
  457. {
  458. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::InitRPC"));
  459. ATLASSERT(NULL == (*pFaxDeviceConfig) );
  460. HRESULT hRc = S_OK;
  461. DWORD ec = ERROR_SUCCESS;
  462. //
  463. // get RPC Handle
  464. //
  465. ATLASSERT(m_pFaxServer);
  466. if (!m_pFaxServer->GetFaxServerHandle())
  467. {
  468. ec= GetLastError();
  469. DebugPrintEx(
  470. DEBUG_ERR,
  471. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  472. ec);
  473. goto Error;
  474. }
  475. //
  476. // Retrieve the Device configuration
  477. //
  478. if (!FaxGetPortEx(m_pFaxServer->GetFaxServerHandle(),
  479. m_dwDeviceID,
  480. &( *pFaxDeviceConfig)))
  481. {
  482. ec = GetLastError();
  483. DebugPrintEx(
  484. DEBUG_ERR,
  485. _T("Fail to get device configuration. (ec: %ld)"),
  486. ec);
  487. if (IsNetworkError(ec))
  488. {
  489. DebugPrintEx(
  490. DEBUG_ERR,
  491. _T("Network Error was found. (ec: %ld)"),
  492. ec);
  493. m_pFaxServer->Disconnect();
  494. }
  495. goto Error;
  496. }
  497. //For max verification
  498. ATLASSERT(*pFaxDeviceConfig);
  499. ATLASSERT(ERROR_SUCCESS == ec);
  500. DebugPrintEx( DEBUG_MSG,
  501. _T("Succeed to get device configuration."));
  502. goto Exit;
  503. Error:
  504. ATLASSERT(ERROR_SUCCESS != ec);
  505. hRc = HRESULT_FROM_WIN32(ec);
  506. //Important!!!
  507. *pFaxDeviceConfig = NULL;
  508. NodeMsgBox(GetFaxServerErrorMsg(ec));
  509. Exit:
  510. return (hRc);
  511. }
  512. /*
  513. - CFaxDeviceNode::Init
  514. -
  515. * Purpose:
  516. * Initiates the private members
  517. * from configuration structure pointer.
  518. *
  519. * Arguments:
  520. *
  521. * Return:
  522. * OLE error code
  523. */
  524. HRESULT CFaxDeviceNode::Init( PFAX_PORT_INFO_EX pFaxDeviceConfig)
  525. {
  526. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::Init"));
  527. ATLASSERT(NULL != (pFaxDeviceConfig) );
  528. HRESULT hRc = S_OK;
  529. m_pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  530. if(!m_pFaxServer)
  531. {
  532. ATLASSERT(m_pFaxServer);
  533. return E_FAIL;
  534. }
  535. //
  536. // Constant device members
  537. //
  538. m_dwDeviceID = pFaxDeviceConfig->dwDeviceID;
  539. m_bstrDisplayName = pFaxDeviceConfig->lpctstrDeviceName;
  540. if (!m_bstrDisplayName)
  541. {
  542. hRc = E_OUTOFMEMORY;
  543. goto Error;
  544. }
  545. m_bstrProviderName = pFaxDeviceConfig->lpctstrProviderName;
  546. if (!m_bstrProviderName)
  547. {
  548. hRc = E_OUTOFMEMORY;
  549. goto Error;
  550. }
  551. m_bstrProviderGUID = pFaxDeviceConfig->lpctstrProviderGUID;
  552. if (!m_bstrProviderGUID)
  553. {
  554. hRc = E_OUTOFMEMORY;
  555. goto Error;
  556. }
  557. //
  558. // Varied device members
  559. //
  560. hRc = UpdateMembers(pFaxDeviceConfig);
  561. if (S_OK != hRc)
  562. {
  563. goto Exit; //dbgmsg + MSgBox by called Func.
  564. }
  565. ATLASSERT(S_OK == hRc);
  566. goto Exit;
  567. Error:
  568. ATLASSERT(S_OK != hRc);
  569. DebugPrintEx(
  570. DEBUG_ERR,
  571. _T("Failed to allocate string - out of memory"));
  572. NodeMsgBox(IDS_MEMORY);
  573. Exit:
  574. return (hRc);
  575. }
  576. /*
  577. - CFaxDeviceNode::UpdateMembers
  578. -
  579. * Purpose:
  580. * Initiates the private members
  581. * from configuration structure pointer.
  582. *
  583. * Arguments:
  584. *
  585. * Return:
  586. * OLE error code
  587. */
  588. HRESULT CFaxDeviceNode::UpdateMembers( PFAX_PORT_INFO_EX pFaxDeviceConfig )
  589. {
  590. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::UpdateMembers"));
  591. HRESULT hRc = S_OK;
  592. // func. must been called just
  593. // after a call to retreive config structure
  594. // was done successfully!
  595. ATLASSERT(NULL != pFaxDeviceConfig );
  596. // We are not supporting change of DeviceID
  597. ATLASSERT(m_dwDeviceID == pFaxDeviceConfig->dwDeviceID);
  598. if(!pFaxDeviceConfig->lptstrDescription)
  599. {
  600. m_bstrDescription = L"";
  601. }
  602. else
  603. {
  604. m_bstrDescription = pFaxDeviceConfig->lptstrDescription;
  605. }
  606. if (!m_bstrDescription)
  607. {
  608. hRc = E_OUTOFMEMORY;
  609. goto Error;
  610. }
  611. m_fSend = pFaxDeviceConfig->bSend;
  612. switch (pFaxDeviceConfig->ReceiveMode)
  613. {
  614. case FAX_DEVICE_RECEIVE_MODE_OFF: // Do not answer to incoming calls
  615. m_fAutoReceive = FALSE;
  616. m_fManualReceive = FALSE;
  617. break;
  618. case FAX_DEVICE_RECEIVE_MODE_AUTO: // Automatically answer to incoming calls after dwRings rings
  619. m_fAutoReceive = TRUE;
  620. m_fManualReceive = FALSE;
  621. break;
  622. case FAX_DEVICE_RECEIVE_MODE_MANUAL: // Manually answer to incoming calls - only FaxAnswerCall answers the call
  623. m_fManualReceive = TRUE;
  624. m_fAutoReceive = FALSE;
  625. break;
  626. default:
  627. ATLASSERT(FALSE);
  628. DebugPrintEx(
  629. DEBUG_ERR,
  630. TEXT("Unexpected m_pFaxDeviceConfig->ReceiveMode"));
  631. }
  632. m_dwRings = pFaxDeviceConfig->dwRings;
  633. m_dwStatus = pFaxDeviceConfig->dwStatus;
  634. m_bstrCsid = pFaxDeviceConfig->lptstrCsid;
  635. if (!m_bstrCsid)
  636. {
  637. hRc = E_OUTOFMEMORY;
  638. goto Error;
  639. }
  640. m_bstrTsid = pFaxDeviceConfig->lptstrTsid;
  641. if (!m_bstrTsid)
  642. {
  643. hRc = E_OUTOFMEMORY;
  644. goto Error;
  645. }
  646. ATLASSERT(S_OK == hRc);
  647. goto Exit;
  648. Error:
  649. ATLASSERT(S_OK != hRc);
  650. //Important!!!
  651. //FaxFreeBuffer by called Func.
  652. //(*pFaxDeviceConfig) = NULL;
  653. DebugPrintEx(
  654. DEBUG_ERR,
  655. _T("Failed to allocate string - out of memory"));
  656. NodeMsgBox(IDS_MEMORY);
  657. Exit:
  658. return (hRc);
  659. }
  660. /*
  661. - CFaxDeviceNode::UpdateDeviceStatus
  662. -
  663. * Purpose:
  664. * UpdateDeviceStatus
  665. *
  666. * Arguments:
  667. *
  668. * Return:
  669. * OLE error code
  670. */
  671. HRESULT CFaxDeviceNode::UpdateDeviceStatus( DWORD dwDeviceStatus )
  672. {
  673. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::UpdateDeviceStatus"));
  674. m_dwStatus = dwDeviceStatus;
  675. if ( m_dwStatus & FAX_DEVICE_STATUS_POWERED_OFF)
  676. {
  677. SetIcons(IMAGE_DEVICE_POWERED_OFF, IMAGE_DEVICE_POWERED_OFF);
  678. }
  679. else
  680. {
  681. SetIcons(IMAGE_DEVICE, IMAGE_DEVICE);
  682. }
  683. return S_OK;
  684. }
  685. /*
  686. - CFaxDeviceNode::RefreshAllViews
  687. -
  688. * Purpose:
  689. * Call IResultData::UpdateItem
  690. *
  691. * Arguments:
  692. * [in] pConsole - the console interface
  693. *
  694. * Return:
  695. */
  696. HRESULT
  697. CFaxDeviceNode::RefreshAllViews(IConsole *pConsole)
  698. {
  699. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::RefreshAllViews"));
  700. HRESULT hRc = S_OK;
  701. ATLASSERT( pConsole != NULL );
  702. hRc = pConsole->UpdateAllViews(NULL, NULL, NULL);
  703. if ( FAILED(hRc) )
  704. {
  705. DebugPrintEx(
  706. DEBUG_ERR,
  707. _T("Fail to UpdateAllViews, hRc=%08X"),
  708. hRc);
  709. NodeMsgBox(IDS_REFRESH_VIEW);
  710. }
  711. return hRc;
  712. }
  713. /*
  714. - CFaxDeviceNode::DoRefresh
  715. -
  716. * Purpose:
  717. * Refresh the object .
  718. * First it gets data structure, inits members
  719. * and frees the structure.
  720. * The last thing is to refresh the view.
  721. *
  722. * Arguments:
  723. *
  724. * Return:
  725. * OLE error code
  726. */
  727. HRESULT
  728. CFaxDeviceNode::DoRefresh()
  729. {
  730. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::DoRefresh"));
  731. HRESULT hRc = S_OK;
  732. PFAX_PORT_INFO_EX pFaxDeviceConfig = NULL ;
  733. //
  734. // Get the Config. structure with FaxGetPortEx
  735. //
  736. hRc = InitRPC(&pFaxDeviceConfig);
  737. if (FAILED(hRc))
  738. {
  739. //DebugPrint and MsgBox by called func.
  740. //to be safe actually done by InitRPC on error.
  741. pFaxDeviceConfig = NULL;
  742. goto Error;
  743. }
  744. ATLASSERT(NULL != pFaxDeviceConfig);
  745. //
  746. // init members
  747. //
  748. hRc = UpdateMembers(pFaxDeviceConfig);
  749. if (FAILED(hRc))
  750. {
  751. //DebugPrint and MsgBox by called func.
  752. goto Error;
  753. }
  754. //
  755. // Free Buffer - Important!!!
  756. // == done on exit ==
  757. //
  758. //
  759. // Refresh only this device's view
  760. //
  761. hRc = RefreshTheView();
  762. if (FAILED(hRc))
  763. {
  764. //DebugPrint and MsgBox by called func.
  765. goto Error;
  766. }
  767. ATLASSERT(S_OK == hRc);
  768. goto Exit;
  769. Error:
  770. ATLASSERT(S_OK != hRc);
  771. if ( FAILED(hRc) )
  772. {
  773. DebugPrintEx(
  774. DEBUG_ERR,
  775. _T("Failed to Refresh (hRc : %08X)"),
  776. hRc);
  777. }
  778. Exit:
  779. if (NULL != pFaxDeviceConfig)
  780. {
  781. FaxFreeBuffer(pFaxDeviceConfig);
  782. pFaxDeviceConfig = NULL;
  783. }//any way function quits with memory allocation freed
  784. return hRc;
  785. }
  786. /*
  787. - CFaxDeviceNode::OnRefresh
  788. -
  789. * Purpose:
  790. * Called by MMC to refresh the object .
  791. * First it gets data structure, inits members
  792. * and frees the structure.
  793. * Second thing is recursive refresh.
  794. * The third thing is to refresh the view.
  795. *
  796. * Arguments:
  797. *
  798. * Return:
  799. * OLE error code
  800. */
  801. HRESULT
  802. CFaxDeviceNode::OnRefresh(LPARAM arg,
  803. LPARAM param,
  804. IComponentData *pComponentData,
  805. IComponent * pComponent,
  806. DATA_OBJECT_TYPES type)
  807. {
  808. UNREFERENCED_PARAMETER (arg);
  809. UNREFERENCED_PARAMETER (param);
  810. UNREFERENCED_PARAMETER (pComponentData);
  811. UNREFERENCED_PARAMETER (pComponent);
  812. UNREFERENCED_PARAMETER (type);
  813. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::OnRefresh"));
  814. return DoRefresh();
  815. }
  816. /*
  817. - CFaxDeviceNode::UpdateMenuState
  818. -
  819. * Purpose:
  820. * Overrides the ATL CSnapInItemImpl::UpdateMenuState
  821. * which only have one line inside it "return;"
  822. * This function implements an update for the check mark
  823. * beside the Receive and the Send menus.
  824. *
  825. * Arguments:
  826. * [in] id - unsigned int with the menu IDM value
  827. * [out] pBuf - string
  828. * [out] flags - pointer to flags state combination unsigned int
  829. *
  830. * Return:
  831. * no return value - void function
  832. */
  833. void CFaxDeviceNode::UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  834. {
  835. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::UpdateMenuState"));
  836. UNREFERENCED_PARAMETER (pBuf);
  837. ATLASSERT(m_fManualReceive && m_fAutoReceive); //plese see: "[yossg] Please notice" above.
  838. switch (id)
  839. {
  840. case IDM_FAX_DEVICE_SEND:
  841. *flags = (m_fSend ? MF_ENABLED | MF_CHECKED : MF_ENABLED | MF_UNCHECKED);
  842. break;
  843. case IDM_FAX_DEVICE_RECEIVE_AUTO:
  844. *flags = (m_fAutoReceive ? MF_ENABLED | MF_CHECKED : MF_ENABLED | MF_UNCHECKED);
  845. break;
  846. case IDM_FAX_DEVICE_RECEIVE_MANUAL:
  847. if(m_pFaxServer->GetServerAPIVersion() == FAX_API_VERSION_0)
  848. {
  849. //
  850. // The remote fax server is SBS/BOS 2000
  851. // is does not support manual answering
  852. //
  853. *flags = MF_DISABLED | MF_GRAYED | MF_UNCHECKED;
  854. }
  855. else
  856. {
  857. *flags = (m_fManualReceive ? MF_ENABLED | MF_CHECKED : MF_ENABLED | MF_UNCHECKED);
  858. }
  859. break;
  860. default:
  861. break;
  862. }
  863. return;
  864. }
  865. /*
  866. - CFaxDeviceNode::OnFaxReceive
  867. -
  868. * Purpose:
  869. * Called when Receive Faxes was pushed.
  870. *
  871. * Arguments:
  872. *
  873. * Return:
  874. * OLE error code
  875. */
  876. HRESULT CFaxDeviceNode::OnFaxReceive (UINT nID, bool &bHandled, CSnapInObjectRootBase *pRoot)
  877. {
  878. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::OnFaxReceive"));
  879. HRESULT hRc = S_OK;
  880. // The check mark state
  881. BOOL fNewState;
  882. if ( IDM_FAX_DEVICE_RECEIVE_AUTO == nID)
  883. {
  884. fNewState = !m_fAutoReceive;
  885. }
  886. else if (IDM_FAX_DEVICE_RECEIVE_MANUAL == nID)
  887. {
  888. fNewState = !m_fManualReceive;
  889. }
  890. else
  891. {
  892. ATLASSERT(FALSE);
  893. DebugPrintEx(
  894. DEBUG_ERR,
  895. _T("Unexpected function call. (hRc: %08X)"),
  896. hRc);
  897. hRc = E_UNEXPECTED;
  898. goto Exit;
  899. }
  900. hRc = FaxChangeState(nID, fNewState);
  901. if ( S_OK != hRc )
  902. {
  903. //DebugPrint in the function layer
  904. return S_FALSE;
  905. }
  906. //
  907. // Service succeded. now change member
  908. //
  909. // Update new state(s) done here by FaxChangeState;
  910. //
  911. // In case Manual Receive was taken we do not have to refresh the view
  912. // In such a case all devices are refreshed !!!
  913. //
  914. Exit:
  915. return hRc;
  916. }
  917. /*
  918. - CFaxDeviceNode::OnFaxSend
  919. -
  920. * Purpose:
  921. * Called when Send Faxes was pushed.
  922. *
  923. * Arguments:
  924. *
  925. * Return:
  926. * OLE error code
  927. */
  928. HRESULT CFaxDeviceNode::OnFaxSend(bool &bHandled, CSnapInObjectRootBase *pRoot)
  929. {
  930. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::OnFaxSend"));
  931. HRESULT hRc = S_OK;
  932. // The check mark state
  933. BOOL fNewState;
  934. fNewState = !m_fSend;
  935. hRc = FaxChangeState(IDM_FAX_DEVICE_SEND, fNewState);
  936. if ( S_OK != hRc )
  937. {
  938. //DebugPrint in the function layer
  939. return S_FALSE;
  940. }
  941. //
  942. // Service succeded. now change member
  943. //
  944. m_fSend = fNewState;
  945. //
  946. // Refresh the view
  947. //
  948. hRc = RefreshTheView();
  949. if ( S_OK != hRc )
  950. {
  951. DebugPrintEx(
  952. DEBUG_ERR,
  953. _T("Fail to RefreshTheView(). (hRc: %08X)"),
  954. hRc);
  955. goto Exit;
  956. }
  957. Exit:
  958. return hRc;
  959. }
  960. /*
  961. - CFaxDeviceNode::FaxChangeState
  962. -
  963. * Purpose:
  964. * .
  965. *
  966. * Arguments:
  967. *
  968. * Return:
  969. * OLE error code
  970. */
  971. HRESULT CFaxDeviceNode::FaxChangeState(UINT uiIDM, BOOL fState)
  972. {
  973. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::FaxChangeState"));
  974. HRESULT hRc = S_OK;
  975. DWORD ec = ERROR_SUCCESS;
  976. // check input
  977. ATLASSERT(
  978. (IDM_FAX_DEVICE_RECEIVE == uiIDM)
  979. ||
  980. (IDM_FAX_DEVICE_SEND_AUTO == uiIDM)
  981. ||
  982. (IDM_FAX_DEVICE_RECEIVE_MANUAL == uiIDM)
  983. );
  984. PFAX_PORT_INFO_EX pFaxDeviceInfo = NULL;
  985. //
  986. // Get Configuration
  987. //
  988. ATLASSERT(m_pFaxServer);
  989. if (!m_pFaxServer->GetFaxServerHandle())
  990. {
  991. ec= GetLastError();
  992. DebugPrintEx(
  993. DEBUG_ERR,
  994. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  995. ec);
  996. goto Error;
  997. }
  998. // Retrieve the Device configuration
  999. if (!FaxGetPortEx(m_pFaxServer->GetFaxServerHandle(),
  1000. m_dwDeviceID,
  1001. &pFaxDeviceInfo))
  1002. {
  1003. ec = GetLastError();
  1004. DebugPrintEx(
  1005. DEBUG_ERR,
  1006. _T("Fail to get device configuration. (ec: %ld)"),
  1007. ec);
  1008. if (IsNetworkError(ec))
  1009. {
  1010. DebugPrintEx(
  1011. DEBUG_ERR,
  1012. _T("Network Error was found. (ec: %ld)"),
  1013. ec);
  1014. m_pFaxServer->Disconnect();
  1015. }
  1016. goto Error;
  1017. }
  1018. //For max verification
  1019. ATLASSERT(pFaxDeviceInfo);
  1020. DebugPrintEx( DEBUG_MSG,
  1021. _T("Succeed to get device configuration."));
  1022. //
  1023. // Change State
  1024. //
  1025. switch (uiIDM)
  1026. {
  1027. case IDM_FAX_DEVICE_SEND:
  1028. pFaxDeviceInfo->bSend = fState;
  1029. break;
  1030. case IDM_FAX_DEVICE_RECEIVE_AUTO:
  1031. pFaxDeviceInfo->ReceiveMode =
  1032. ( fState ? FAX_DEVICE_RECEIVE_MODE_AUTO : FAX_DEVICE_RECEIVE_MODE_OFF);
  1033. break;
  1034. case IDM_FAX_DEVICE_RECEIVE_MANUAL:
  1035. pFaxDeviceInfo->ReceiveMode =
  1036. ( fState ? FAX_DEVICE_RECEIVE_MODE_MANUAL : FAX_DEVICE_RECEIVE_MODE_OFF);
  1037. break;
  1038. }
  1039. //
  1040. // Set Configuration
  1041. //
  1042. if (!FaxSetPortEx(
  1043. m_pFaxServer->GetFaxServerHandle(),
  1044. m_dwDeviceID,
  1045. pFaxDeviceInfo))
  1046. {
  1047. ec = GetLastError();
  1048. DebugPrintEx(
  1049. DEBUG_ERR,
  1050. _T("Fail to Set device configuration. (ec: %ld)"),
  1051. ec);
  1052. if ( FAX_ERR_DEVICE_NUM_LIMIT_EXCEEDED == ec )
  1053. {
  1054. hRc = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
  1055. NodeMsgBox(IDS_ERR_ADMIN_DEVICE_LIMIT, MB_OK|MB_ICONEXCLAMATION);
  1056. goto Exit;
  1057. }
  1058. if (IsNetworkError(ec))
  1059. {
  1060. DebugPrintEx(
  1061. DEBUG_ERR,
  1062. _T("Network Error was found. (ec: %ld)"),
  1063. ec);
  1064. m_pFaxServer->Disconnect();
  1065. }
  1066. goto Error;
  1067. }
  1068. //
  1069. // Set members in cases of Receive
  1070. //
  1071. if ( uiIDM == IDM_FAX_DEVICE_RECEIVE_AUTO || uiIDM == IDM_FAX_DEVICE_RECEIVE_MANUAL)
  1072. {
  1073. if ( FAX_DEVICE_RECEIVE_MODE_MANUAL == pFaxDeviceInfo->ReceiveMode )
  1074. {
  1075. ATLASSERT(m_pParentNode);
  1076. hRc = m_pParentNode->DoRefresh();
  1077. if (S_OK != hRc)
  1078. {
  1079. DebugPrintEx(DEBUG_ERR,
  1080. _T("Fail to call DoRefresh(). (hRc: %08X)"),
  1081. hRc);
  1082. goto Error;
  1083. }
  1084. }
  1085. else
  1086. {
  1087. hRc = DoRefresh();
  1088. if ( FAILED(hRc) )
  1089. {
  1090. DebugPrintEx(
  1091. DEBUG_ERR,
  1092. _T("Fail to call DoRefresh. (hRc: %08X)"),
  1093. hRc);
  1094. }
  1095. }
  1096. }
  1097. ATLASSERT(ERROR_SUCCESS == ec);
  1098. DebugPrintEx( DEBUG_MSG,
  1099. _T("Succeed to set device configuration."));
  1100. goto Exit;
  1101. Error:
  1102. ATLASSERT(ERROR_SUCCESS != ec);
  1103. hRc = HRESULT_FROM_WIN32(ec);
  1104. NodeMsgBox(GetFaxServerErrorMsg(ec));
  1105. Exit:
  1106. if ( NULL != pFaxDeviceInfo )
  1107. FaxFreeBuffer(pFaxDeviceInfo);
  1108. return hRc;
  1109. }
  1110. HRESULT
  1111. CFaxDeviceNode::RefreshTheView()
  1112. {
  1113. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::RefreshTheView"));
  1114. HRESULT hRc = S_OK;
  1115. ATLASSERT( m_pComponentData != NULL );
  1116. ATLASSERT( m_pComponentData->m_spConsole != NULL );
  1117. CComPtr<IConsole> spConsole;
  1118. spConsole = m_pComponentData->m_spConsole;
  1119. CComQIPtr<IConsoleNameSpace,&IID_IConsoleNameSpace> spNamespace( spConsole );
  1120. SCOPEDATAITEM* pScopeData;
  1121. //
  1122. // Get the updated SCOPEDATAITEM
  1123. //
  1124. hRc = GetScopeData( &pScopeData );
  1125. if (FAILED(hRc))
  1126. {
  1127. DebugPrintEx(
  1128. DEBUG_ERR,
  1129. TEXT("Fail to get pScopeData. (hRc: %08X)"),
  1130. hRc);
  1131. goto Error;
  1132. }
  1133. //
  1134. // This will force MMC to redraw the scope group node
  1135. //
  1136. hRc = spNamespace->SetItem( pScopeData );
  1137. if (FAILED(hRc))
  1138. {
  1139. DebugPrintEx(
  1140. DEBUG_ERR,
  1141. TEXT("Fail to set Item pScopeData. (hRc: %08X)"),
  1142. hRc);
  1143. goto Error;
  1144. }
  1145. ATLASSERT( S_OK != hRc);
  1146. goto Exit;
  1147. Error:
  1148. NodeMsgBox(IDS_FAIL2REFRESH_DEVICE);
  1149. Exit:
  1150. return hRc;
  1151. }
  1152. /*
  1153. +
  1154. +
  1155. *
  1156. * CFaxDeviceNode::FillData
  1157. *
  1158. *
  1159. * Override CSnapInItem::FillData for private cliboard formats
  1160. *
  1161. *
  1162. * Parameters
  1163. *
  1164. * Return Values
  1165. *
  1166. -
  1167. -
  1168. */
  1169. HRESULT CFaxDeviceNode::FillData(CLIPFORMAT cf, LPSTREAM pStream)
  1170. {
  1171. DEBUG_FUNCTION_NAME( _T("CFaxDeviceNode::FillData"));
  1172. HRESULT hr = DV_E_CLIPFORMAT;
  1173. ULONG uWritten;
  1174. if (cf == m_CFPermanentDeviceID)
  1175. {
  1176. DWORD dwDeviceID;
  1177. dwDeviceID = GetDeviceID();
  1178. hr = pStream->Write((VOID *)&dwDeviceID, sizeof(DWORD), &uWritten);
  1179. return hr;
  1180. }
  1181. if (cf == m_CFFspGuid)
  1182. {
  1183. CComBSTR bstrGUID;
  1184. bstrGUID = GetFspGuid();
  1185. hr = pStream->Write((VOID *)(LPWSTR)bstrGUID, sizeof(WCHAR)*(bstrGUID.Length()+1), &uWritten);
  1186. return hr;
  1187. }
  1188. if (cf == m_CFServerName)
  1189. {
  1190. ATLASSERT(GetRootNode());
  1191. CComBSTR bstrServerName = ((CFaxServerNode *)GetRootNode())->GetServerName();
  1192. if (!bstrServerName)
  1193. {
  1194. DebugPrintEx(
  1195. DEBUG_ERR,
  1196. TEXT("Out of memory. Failed to load string."));
  1197. return E_OUTOFMEMORY;
  1198. }
  1199. hr = pStream->Write((VOID *)(LPWSTR)bstrServerName, sizeof(WCHAR)*(bstrServerName.Length()+1), &uWritten);
  1200. return hr;
  1201. }
  1202. else
  1203. return CSnapInItemImpl<CFaxDeviceNode>::FillData(cf, pStream);
  1204. }
  1205. /*
  1206. +
  1207. + CFaxDeviceNode::OnShowContextHelp
  1208. *
  1209. * Purpose:
  1210. * Overrides CSnapinNode::OnShowContextHelp.
  1211. *
  1212. * Arguments:
  1213. *
  1214. * Return:
  1215. - OLE error code
  1216. -
  1217. */
  1218. HRESULT CFaxDeviceNode::OnShowContextHelp(
  1219. IDisplayHelp* pDisplayHelp, LPOLESTR helpFile)
  1220. {
  1221. return DisplayContextHelp(pDisplayHelp, helpFile, HLP_DEVICES);
  1222. }