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.

713 lines
18 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : InboundRoutingMethod.cpp //
  3. // //
  4. // DESCRIPTION : Implementation of the Inbound Routing Method node. //
  5. // //
  6. // AUTHOR : yossg //
  7. // //
  8. // HISTORY : //
  9. // Dec 1 1999 yossg Created //
  10. // Dec 14 1999 yossg add basic functionality //
  11. // Oct 17 2000 yossg //
  12. // //
  13. // Copyright (C) 1999 Microsoft Corporation All Rights Reserved //
  14. // //
  15. /////////////////////////////////////////////////////////////////////////////
  16. #include "StdAfx.h"
  17. #include "snapin.h"
  18. #include "InboundRoutingMethod.h"
  19. #include "InboundRoutingMethods.h"
  20. #include "FaxServer.h"
  21. #include "FaxServerNode.h"
  22. #include "oaidl.h"
  23. #include "urlmon.h"
  24. #include "mshtmhst.h"
  25. #include "exdisp.h"
  26. #include "faxmmc.h"
  27. /////////////////////////////////////////////////////////////////////////////
  28. // {220D2CB0-85A9-4a43-B6E8-9D66B44F1AF5}
  29. static const GUID CFaxInboundRoutingMethodNodeGUID_NODETYPE = FAXSRV_ROUTING_METHOD_NODETYPE_GUID;
  30. const GUID* CFaxInboundRoutingMethodNode::m_NODETYPE = &CFaxInboundRoutingMethodNodeGUID_NODETYPE;
  31. const OLECHAR* CFaxInboundRoutingMethodNode::m_SZNODETYPE = FAXSRV_ROUTING_METHOD_NODETYPE_GUID_STR;
  32. //const OLECHAR* CnotImplemented::m_SZDISPLAY_NAME = OLESTR("Inbound Routing Methods");
  33. const CLSID* CFaxInboundRoutingMethodNode::m_SNAPIN_CLASSID = &CLSID_Snapin;
  34. CLIPFORMAT CFaxInboundRoutingMethodNode::m_CFExtensionName =
  35. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_ROUTEEXT_NAME);
  36. CLIPFORMAT CFaxInboundRoutingMethodNode::m_CFMethodGuid =
  37. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_ROUTING_METHOD_GUID);
  38. CLIPFORMAT CFaxInboundRoutingMethodNode::m_CFServerName =
  39. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_SERVER_NAME);
  40. CLIPFORMAT CFaxInboundRoutingMethodNode::m_CFDeviceId =
  41. (CLIPFORMAT)RegisterClipboardFormat(CF_MSFAXSRV_DEVICE_ID);
  42. /*
  43. - CFaxInboundRoutingMethodNode::Init
  44. -
  45. * Purpose:
  46. * Init all members icon etc.
  47. *
  48. * Arguments:
  49. * [in] pMethodConfig - PFAX_ROUTING_METHOD
  50. *
  51. * Return:
  52. * OLE error code
  53. */
  54. HRESULT CFaxInboundRoutingMethodNode::Init(PFAX_ROUTING_METHOD pMethodConfig)
  55. {
  56. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::Init"));
  57. HRESULT hRc = S_OK;
  58. ATLASSERT(pMethodConfig);
  59. hRc = InitMembers( pMethodConfig );
  60. if (FAILED(hRc))
  61. {
  62. DebugPrintEx(
  63. DEBUG_ERR,
  64. _T("Failed to InitMembers"));
  65. //NodeMsgBox done by called func.
  66. goto Exit;
  67. }
  68. //
  69. // Icon
  70. //
  71. m_resultDataItem.nImage = (m_fEnabled ? IMAGE_METHOD_ENABLE : IMAGE_METHOD_DISABLE );
  72. Exit:
  73. return hRc;
  74. }
  75. /*
  76. - CFaxInboundRoutingMethodNode::InitMembers
  77. -
  78. * Purpose:
  79. * Private method to initiate members
  80. * Must be called after init of m_pParentNode
  81. *
  82. * Arguments:
  83. * [in] pMethodConfig - PFAX_ROUTING_METHOD structure
  84. *
  85. * Return:
  86. * OLE error code
  87. */
  88. HRESULT CFaxInboundRoutingMethodNode::InitMembers(PFAX_ROUTING_METHOD pMethodConfig)
  89. {
  90. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::InitMembers"));
  91. HRESULT hRc = S_OK;
  92. ATLASSERT(pMethodConfig);
  93. m_dwDeviceID = pMethodConfig->DeviceId;
  94. m_fEnabled = pMethodConfig->Enabled;
  95. m_bstrDisplayName = pMethodConfig->FriendlyName;
  96. if (!m_bstrDisplayName)
  97. {
  98. hRc = E_OUTOFMEMORY;
  99. goto Error;
  100. }
  101. m_bstrFriendlyName = pMethodConfig->FriendlyName;
  102. if (!m_bstrFriendlyName)
  103. {
  104. hRc = E_OUTOFMEMORY;
  105. goto Error;
  106. }
  107. m_bstrMethodGUID = pMethodConfig->Guid;
  108. if (!m_bstrMethodGUID)
  109. {
  110. hRc = E_OUTOFMEMORY;
  111. goto Error;
  112. }
  113. m_bstrExtensionFriendlyName
  114. = pMethodConfig->ExtensionFriendlyName;
  115. if (!m_bstrExtensionFriendlyName)
  116. {
  117. hRc = E_OUTOFMEMORY;
  118. goto Error;
  119. }
  120. m_bstrExtensionImageName
  121. = pMethodConfig->ExtensionImageName;
  122. if (!m_bstrExtensionImageName)
  123. {
  124. hRc = E_OUTOFMEMORY;
  125. goto Error;
  126. }
  127. ATLASSERT(S_OK == hRc);
  128. goto Exit;
  129. Error:
  130. ATLASSERT(S_OK != hRc);
  131. DebugPrintEx(
  132. DEBUG_ERR,
  133. _T("Failed to allocate string - out of memory"));
  134. ATLASSERT(NULL != m_pParentNode);
  135. if (NULL != m_pParentNode)
  136. {
  137. m_pParentNode->NodeMsgBox(IDS_MEMORY);
  138. }
  139. Exit:
  140. return (hRc);
  141. }
  142. /*
  143. - CFaxInboundRoutingMethodNode::GetResultPaneColInfo
  144. -
  145. * Purpose:
  146. * Return the text for specific column
  147. * Called for each column in the result pane
  148. *
  149. * Arguments:
  150. * [in] nCol - column number
  151. *
  152. * Return:
  153. * String to be displayed in the specific column
  154. */
  155. LPOLESTR CFaxInboundRoutingMethodNode::GetResultPaneColInfo(int nCol)
  156. {
  157. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::GetResultPaneColInfo"));
  158. HRESULT hRc = S_OK;
  159. UINT uiResourceId;
  160. m_buf.Empty();
  161. switch (nCol)
  162. {
  163. case 0:
  164. //
  165. // Name
  166. //
  167. if (!m_bstrFriendlyName)
  168. {
  169. DebugPrintEx(
  170. DEBUG_ERR,
  171. TEXT("Null memeber BSTR - m_bstrFriendlyName."));
  172. goto Error;
  173. }
  174. else
  175. {
  176. return (m_bstrFriendlyName);
  177. }
  178. case 1:
  179. //
  180. // Enabled
  181. //
  182. uiResourceId = (m_fEnabled ? IDS_FXS_YES : IDS_FXS_NO);
  183. if (!m_buf.LoadString(_Module.GetResourceInstance(), uiResourceId) )
  184. {
  185. DebugPrintEx(
  186. DEBUG_ERR,
  187. TEXT("Fail to load string for the method enabled value."));
  188. goto Error;
  189. }
  190. else
  191. {
  192. return (m_buf);
  193. }
  194. case 2:
  195. //
  196. // Extension
  197. //
  198. if (!m_bstrExtensionFriendlyName)
  199. {
  200. DebugPrintEx(
  201. DEBUG_ERR,
  202. TEXT("Null memeber BSTR - m_bstrExtensionFriendlyName."));
  203. goto Error;
  204. }
  205. else
  206. {
  207. return (m_bstrExtensionFriendlyName);
  208. }
  209. default:
  210. ATLASSERT(0); // "this number of column is not supported "
  211. return(L"");
  212. } // endswitch (nCol)
  213. Error:
  214. return(L"???");
  215. }
  216. /*
  217. - CFaxInboundRoutingMethodNode::CreatePropertyPages
  218. -
  219. * Purpose:
  220. * Called when creating a property page of the object
  221. *
  222. * Arguments:
  223. * [in] lpProvider - The property sheet
  224. * [in] handle - Handle for notification
  225. * [in] pUnk - Pointer to the data object
  226. * [in] type - CCT_* (SCOPE, RESULT, ...)
  227. *
  228. * Return:
  229. * OLE error code
  230. */
  231. HRESULT
  232. CFaxInboundRoutingMethodNode::CreatePropertyPages(LPPROPERTYSHEETCALLBACK lpProvider,
  233. LONG_PTR handle,
  234. IUnknown *pUnk,
  235. DATA_OBJECT_TYPES type)
  236. {
  237. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::CreatePropertyPages"));
  238. HRESULT hRc = S_OK;
  239. ATLASSERT(lpProvider);
  240. ATLASSERT(type == CCT_RESULT || type == CCT_SCOPE);
  241. //
  242. // Initiate
  243. //
  244. m_pInboundRoutingMethodGeneral = NULL;
  245. //
  246. // General
  247. //
  248. m_pInboundRoutingMethodGeneral = new CppFaxInboundRoutingMethod(
  249. handle,
  250. this,
  251. TRUE,
  252. _Module.GetResourceInstance());
  253. if (!m_pInboundRoutingMethodGeneral)
  254. {
  255. hRc = E_OUTOFMEMORY;
  256. NodeMsgBox(IDS_MEMORY_FAIL_TO_OPEN_PP);
  257. goto Error;
  258. }
  259. /*
  260. * not exists : m_pPP..->InitRPC();
  261. */
  262. hRc = lpProvider->AddPage(m_pInboundRoutingMethodGeneral->Create());
  263. if (FAILED(hRc))
  264. {
  265. DebugPrintEx(
  266. DEBUG_ERR,
  267. TEXT("Fail to add property page for General tab. (hRc: %08X)"),
  268. hRc);
  269. NodeMsgBox(IDS_FAIL_TO_OPEN_PROP_PAGE);
  270. goto Error;
  271. }
  272. ATLASSERT(S_OK == hRc);
  273. goto Exit;
  274. Error:
  275. ATLASSERT(S_OK != hRc);
  276. if ( NULL != m_pInboundRoutingMethodGeneral )
  277. {
  278. delete m_pInboundRoutingMethodGeneral;
  279. m_pInboundRoutingMethodGeneral = NULL;
  280. }
  281. Exit:
  282. return hRc;
  283. }
  284. /*
  285. - CFaxInboundRoutingMethodNode::SetVerbs
  286. -
  287. * Purpose:
  288. * What verbs to enable/disable when this object is selected
  289. *
  290. * Arguments:
  291. * [in] pConsoleVerb - MMC ConsoleVerb interface
  292. *
  293. * Return:
  294. * OLE Error code
  295. */
  296. HRESULT CFaxInboundRoutingMethodNode::SetVerbs(IConsoleVerb *pConsoleVerb)
  297. {
  298. HRESULT hRc = S_OK;
  299. //
  300. // Display verbs that we support:
  301. // 1. Properties
  302. //
  303. hRc = pConsoleVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE);
  304. //
  305. // We want the default verb to be Properties
  306. //
  307. hRc = pConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  308. return hRc;
  309. }
  310. /*
  311. - CFaxInboundRoutingMethodNode::OnMethodEnabled
  312. -
  313. * Purpose:
  314. * Called when Enable /Disable menu was pushed.
  315. *
  316. * Arguments:
  317. *
  318. * Return:
  319. * OLE error code
  320. */
  321. HRESULT CFaxInboundRoutingMethodNode::OnMethodEnabled (bool &bHandled, CSnapInObjectRootBase *pRoot)
  322. {
  323. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::OnMethodEnabled"));
  324. HRESULT hRc = S_OK;
  325. BOOL fNewState;
  326. fNewState = !m_fEnabled;
  327. hRc = ChangeEnable( fNewState);
  328. if ( S_OK != hRc )
  329. {
  330. //DebugPrint in the function layer
  331. return S_FALSE;
  332. }
  333. //
  334. // Service succeded. now change member
  335. //
  336. m_fEnabled = fNewState;
  337. //
  338. // Refresh the result pane view
  339. //
  340. m_resultDataItem.nImage = (m_fEnabled ? IMAGE_METHOD_ENABLE : IMAGE_METHOD_DISABLE );
  341. hRc = RefreshSingleResultItem(pRoot);
  342. if (FAILED(hRc))
  343. {
  344. DebugPrintEx(
  345. DEBUG_ERR,
  346. TEXT("Fail to RefreshSingleResultItem. (hRc: %08X)"),
  347. hRc);
  348. NodeMsgBox(IDS_FAIL_TOREFRESH_INMETHOD_NODE);
  349. }
  350. return hRc;
  351. }
  352. /*
  353. - CFaxInboundRoutingMethodNode::ChangeEnable
  354. -
  355. * Purpose:
  356. * .
  357. *
  358. * Arguments:
  359. *
  360. * Return:
  361. * OLE error code
  362. */
  363. HRESULT CFaxInboundRoutingMethodNode::ChangeEnable(BOOL fState)
  364. {
  365. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::ChangeEnable"));
  366. HRESULT hRc = S_OK;
  367. DWORD ec = ERROR_SUCCESS;
  368. CFaxServer * pFaxServer = NULL;
  369. HANDLE hFaxPortHandle = NULL;
  370. //
  371. // Get RPC Handle
  372. //
  373. pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  374. ATLASSERT(pFaxServer);
  375. if (!pFaxServer->GetFaxServerHandle())
  376. {
  377. ec= GetLastError();
  378. DebugPrintEx(
  379. DEBUG_ERR,
  380. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  381. ec);
  382. goto Error;
  383. }
  384. //
  385. // Get Fax Device Handle
  386. //
  387. ATLASSERT(m_pParentNode);
  388. // only a valid handle with PORT_OPEN_MODIFY accepted here!
  389. if (!FaxOpenPort( pFaxServer->GetFaxServerHandle(),
  390. m_dwDeviceID,
  391. PORT_OPEN_MODIFY | PORT_OPEN_QUERY,
  392. &hFaxPortHandle ))
  393. {
  394. ec = GetLastError();
  395. // if modification handle is currently shared
  396. // ec == ERROR_INVALID_HANDLE
  397. if (ERROR_INVALID_HANDLE == ec)
  398. {
  399. //Special case of ERROR_INVALID_HANDLE
  400. DebugPrintEx(DEBUG_ERR,
  401. _T("FaxOpenPort() failed with ERROR_INVALID_HANDLE. (ec:%ld)"),
  402. ec);
  403. NodeMsgBox(IDS_OPENPORT_INVALID_HANDLE);
  404. hRc = HRESULT_FROM_WIN32(ec);
  405. goto Exit;
  406. }
  407. DebugPrintEx(DEBUG_ERR,
  408. _T("FaxOpenPort() failed with. (ec:%ld)"),
  409. ec);
  410. goto Error;
  411. }
  412. ATLASSERT(NULL != hFaxPortHandle);
  413. //
  414. // Set Enabled
  415. //
  416. if (!FaxEnableRoutingMethod(
  417. hFaxPortHandle,
  418. m_bstrMethodGUID,
  419. fState))
  420. {
  421. ec = GetLastError();
  422. //
  423. // 1) Warning
  424. //
  425. if (ERROR_BAD_CONFIGURATION == ec && fState)
  426. {
  427. DebugPrintEx(
  428. DEBUG_WRN,
  429. _T("Cannot enable routing method. The method configuration has some invalid data.(ec: %ld)"),
  430. ec);
  431. hRc = HRESULT_FROM_WIN32(ec);
  432. //
  433. // The routing method is not configured.
  434. // Suggest to configure it.
  435. //
  436. int nRes = IDNO;
  437. NodeMsgBox(IDS_FAIL2ENABLE_METHOD, MB_YESNO | MB_ICONEXCLAMATION, &nRes);
  438. if(IDYES == nRes)
  439. {
  440. InvokePropSheet(this, CCT_RESULT, reinterpret_cast<IUnknown*>(m_pComponentData), m_bstrFriendlyName, 1);
  441. }
  442. goto Exit;
  443. }
  444. //
  445. // 2) Error
  446. //
  447. //
  448. // a) Network Error
  449. //
  450. if (IsNetworkError(ec))
  451. {
  452. DebugPrintEx(
  453. DEBUG_ERR,
  454. _T("Network error was found. (ec: %ld)"),
  455. ec);
  456. pFaxServer->Disconnect();
  457. goto Error;
  458. }
  459. //
  460. // b) General Error
  461. //
  462. DebugPrintEx(
  463. DEBUG_ERR,
  464. _T("Fail to enable /disable routing method. (ec: %ld)"),
  465. ec);
  466. NodeMsgBox(IDS_FAIL2ENABLE_METHOD_ERR);
  467. hRc = HRESULT_FROM_WIN32(ec);
  468. goto Exit;
  469. }
  470. ATLASSERT(ERROR_SUCCESS == ec);
  471. goto Exit;
  472. Error:
  473. ATLASSERT(ERROR_SUCCESS != ec);
  474. hRc = HRESULT_FROM_WIN32(ec);
  475. NodeMsgBox(GetFaxServerErrorMsg(ec));
  476. Exit:
  477. //
  478. // Close Fax Port handle
  479. //
  480. if (NULL != hFaxPortHandle)
  481. {
  482. if (!FaxClose( hFaxPortHandle ))
  483. {
  484. DebugPrintEx(
  485. DEBUG_ERR,
  486. TEXT("FaxClose() on port handle failed (ec: %ld)"),
  487. GetLastError());
  488. }
  489. }
  490. return hRc;
  491. }
  492. /*
  493. - CFaxInboundRoutingMethodNode::UpdateMenuState
  494. -
  495. * Purpose:
  496. * Overrides the ATL CSnapInItemImpl::UpdateMenuState
  497. * which only have one line inside it "return;"
  498. * This function implements the grayed\ungrayed view for the
  499. * the Enable and the Disable menus.
  500. *
  501. * Arguments:
  502. * [in] id - unsigned int with the menu IDM value
  503. * [out] pBuf - string
  504. * [out] flags - pointer to flags state combination unsigned int
  505. *
  506. * Return:
  507. * no return value - void function
  508. */
  509. void CFaxInboundRoutingMethodNode::UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  510. {
  511. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::UpdateMenuState"));
  512. UNREFERENCED_PARAMETER (pBuf);
  513. switch (id)
  514. {
  515. case IDM_FAX_INMETHOD_ENABLE:
  516. *flags = (m_fEnabled ? MF_GRAYED : MF_ENABLED );
  517. break;
  518. case IDM_FAX_INMETHOD_DISABLE:
  519. *flags = (m_fEnabled ? MF_ENABLED : MF_GRAYED );
  520. break;
  521. default:
  522. break;
  523. }
  524. return;
  525. }
  526. /*
  527. +
  528. +
  529. *
  530. * CFaxInboundRoutingMethodNode::FillData
  531. *
  532. *
  533. * Override CSnapInItem::FillData for private cliboard formats
  534. *
  535. *
  536. * Parameters
  537. *
  538. * Return Values
  539. *
  540. -
  541. -
  542. */
  543. HRESULT CFaxInboundRoutingMethodNode::FillData(CLIPFORMAT cf, LPSTREAM pStream)
  544. {
  545. DEBUG_FUNCTION_NAME( _T("CFaxInboundRoutingMethodNode::FillData"));
  546. HRESULT hr = DV_E_CLIPFORMAT;
  547. ULONG uWritten;
  548. if (cf == m_CFExtensionName)
  549. {
  550. hr = pStream->Write((VOID *)(LPWSTR)m_bstrExtensionImageName,
  551. sizeof(WCHAR)*(m_bstrExtensionImageName.Length()+1),
  552. &uWritten);
  553. return hr;
  554. }
  555. if (cf == m_CFMethodGuid)
  556. {
  557. hr = pStream->Write((VOID *)(LPWSTR)m_bstrMethodGUID,
  558. sizeof(WCHAR)*(m_bstrMethodGUID.Length()+1),
  559. &uWritten);
  560. return hr;
  561. }
  562. if (cf == m_CFServerName)
  563. {
  564. CComBSTR bstrServerName = ((CFaxServerNode *)GetRootNode())->GetServerName();
  565. hr = pStream->Write((VOID *)(LPWSTR)bstrServerName,
  566. sizeof(WCHAR)*(bstrServerName.Length()+1),
  567. &uWritten);
  568. return hr;
  569. }
  570. if (cf == m_CFDeviceId)
  571. {
  572. hr = pStream->Write((VOID *)&m_dwDeviceID, sizeof(DWORD), &uWritten);
  573. return hr;
  574. }
  575. return CSnapInItemImpl<CFaxInboundRoutingMethodNode>::FillData(cf, pStream);
  576. } // CFaxInboundRoutingMethodNode::FillData
  577. /*
  578. +
  579. + CFaxInboundRoutingMethodNode::OnShowContextHelp
  580. *
  581. * Purpose:
  582. * Overrides CSnapinNode::OnShowContextHelp.
  583. *
  584. * Arguments:
  585. *
  586. * Return:
  587. - OLE error code
  588. -
  589. */
  590. HRESULT CFaxInboundRoutingMethodNode::OnShowContextHelp(
  591. IDisplayHelp* pDisplayHelp, LPOLESTR helpFile)
  592. {
  593. return DisplayContextHelp(pDisplayHelp, helpFile, HLP_INBOUND_ROUTING);
  594. }