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.

1713 lines
41 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : OutboundGroup.cpp //
  3. // //
  4. // DESCRIPTION : Fax Outbound Routing Group MMC node. //
  5. // //
  6. // AUTHOR : yossg //
  7. // //
  8. // HISTORY : //
  9. // Dec 23 1999 yossg Create //
  10. // Jan 3 2000 yossg add new device(s) //
  11. // Oct 17 2000 yossg //
  12. // //
  13. // Copyright (C) 1999 - 2000 Microsoft Corporation All Rights Reserved //
  14. /////////////////////////////////////////////////////////////////////////////
  15. #include "StdAfx.h"
  16. #include "snapin.h"
  17. #include "FaxServer.h"
  18. #include "FaxServerNode.h"
  19. #include "OutboundGroup.h"
  20. #include "OutboundGroups.h"
  21. #include "dlgNewDevice.h"
  22. //#include "oaidl.h"
  23. #include "Icons.h"
  24. //////////////////////////////////////////////////////////////
  25. // {3E470227-76C1-4b66-9C63-B77DF81C145D}
  26. static const GUID CFaxOutboundRoutingGroupNodeGUID_NODETYPE =
  27. { 0x3e470227, 0x76c1, 0x4b66, { 0x9c, 0x63, 0xb7, 0x7d, 0xf8, 0x1c, 0x14, 0x5d } };
  28. const GUID* CFaxOutboundRoutingGroupNode::m_NODETYPE = &CFaxOutboundRoutingGroupNodeGUID_NODETYPE;
  29. const OLECHAR* CFaxOutboundRoutingGroupNode::m_SZNODETYPE = OLESTR("3E470227-76C1-4b66-9C63-B77DF81C145D");
  30. const CLSID* CFaxOutboundRoutingGroupNode::m_SNAPIN_CLASSID = &CLSID_Snapin;
  31. CColumnsInfo CFaxOutboundRoutingGroupNode::m_ColsInfo;
  32. /*
  33. - CFaxOutboundRoutingGroupNode::RefreshFromRPC
  34. -
  35. * Purpose:
  36. * Init all members icon etc.
  37. * - with creation of structure configuration
  38. * - Call InitRpc to fill it
  39. * - Call InitMembers to init members and icon
  40. * - Free structure
  41. *
  42. * Arguments:
  43. *
  44. * Return:
  45. * OLE error code
  46. */
  47. HRESULT CFaxOutboundRoutingGroupNode::RefreshFromRPC()
  48. {
  49. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::RefreshFromRPC()"));
  50. PFAX_OUTBOUND_ROUTING_GROUP pFaxGroupsConfig = NULL;
  51. HRESULT hRc = S_OK;
  52. DWORD ec = ERROR_SUCCESS;
  53. CFaxServer * pFaxServer = NULL;
  54. DWORD dwNumOfGroups = 0;
  55. BOOL fFound;
  56. DWORD i; //index
  57. PFAX_OUTBOUND_ROUTING_GROUP pFaxTmp;
  58. //
  59. // get Fax Handle
  60. //
  61. pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  62. ATLASSERT(pFaxServer);
  63. if (!pFaxServer->GetFaxServerHandle())
  64. {
  65. ec= GetLastError();
  66. DebugPrintEx(
  67. DEBUG_ERR,
  68. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  69. ec);
  70. goto Error;
  71. }
  72. //
  73. // Retrieve the Outbound Groups configuration
  74. //
  75. if (!FaxEnumOutboundGroups(pFaxServer->GetFaxServerHandle(),
  76. &pFaxGroupsConfig,
  77. &dwNumOfGroups))
  78. {
  79. ec = GetLastError();
  80. DebugPrintEx(
  81. DEBUG_ERR,
  82. _T("Fail to get groups configuration. (ec: %ld)"),
  83. ec);
  84. if (IsNetworkError(ec))
  85. {
  86. DebugPrintEx(
  87. DEBUG_ERR,
  88. _T("Network Error was found. (ec: %ld)"),
  89. ec);
  90. pFaxServer->Disconnect();
  91. }
  92. goto Error;
  93. }
  94. //For max verification
  95. ATLASSERT(pFaxGroupsConfig);
  96. pFaxTmp = pFaxGroupsConfig;
  97. fFound = FALSE;
  98. for ( i =0; i < dwNumOfGroups; i++ )
  99. {
  100. ATLASSERT(NULL != pFaxTmp);
  101. if(0 == wcscmp(m_bstrGroupName, pFaxTmp->lpctstrGroupName) )
  102. {
  103. fFound = TRUE;
  104. }
  105. else
  106. {
  107. pFaxTmp++;
  108. }
  109. }
  110. if(fFound)
  111. {
  112. //
  113. // init members
  114. //
  115. m_dwNumOfDevices = pFaxTmp->dwNumDevices;
  116. if (0 < m_dwNumOfDevices)
  117. {
  118. if (NULL != m_dwNumOfDevices)
  119. {
  120. delete[] m_lpdwDeviceID;
  121. }
  122. m_lpdwDeviceID = new DWORD[m_dwNumOfDevices];
  123. memcpy(m_lpdwDeviceID, pFaxTmp->lpdwDevices, sizeof(DWORD)*m_dwNumOfDevices) ;
  124. }
  125. else
  126. {
  127. DebugPrintEx( DEBUG_MSG, _T("Device list found to be currrently empty."));
  128. if (NULL != m_dwNumOfDevices)
  129. {
  130. delete[] m_lpdwDeviceID;
  131. }
  132. m_lpdwDeviceID = NULL;
  133. }
  134. m_enumStatus = pFaxTmp->Status;
  135. InitIcons ();
  136. }
  137. else
  138. {
  139. ec = FAX_ERR_GROUP_NOT_FOUND;
  140. DebugPrintEx(
  141. DEBUG_ERR,
  142. _T("UEXPECTED ERROR - Group not found."));
  143. goto Error;
  144. }
  145. ATLASSERT(ERROR_SUCCESS == ec);
  146. DebugPrintEx( DEBUG_MSG,
  147. _T("Succeed to re init group configuration and ."));
  148. goto Exit;
  149. Error:
  150. ATLASSERT(ERROR_SUCCESS != ec);
  151. hRc = HRESULT_FROM_WIN32(ec);
  152. NodeMsgBox(GetFaxServerErrorMsg(ec));
  153. Exit:
  154. if (NULL != pFaxGroupsConfig)
  155. {
  156. FaxFreeBuffer(pFaxGroupsConfig);
  157. }//any way function ends with memory allocation freed
  158. return hRc;
  159. }
  160. /*
  161. - CFaxOutboundRoutingGroupNode::Init
  162. -
  163. * Purpose:
  164. * Init all members icon etc.
  165. *
  166. * Arguments:
  167. * [in] pGroupConfig - FAX_OUTBOUND_ROUTING_GROUP
  168. *
  169. * Return:
  170. * OLE error code
  171. */
  172. HRESULT CFaxOutboundRoutingGroupNode::Init(PFAX_OUTBOUND_ROUTING_GROUP pGroupConfig)
  173. {
  174. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::Init"));
  175. HRESULT hRc = S_OK;
  176. ATLASSERT(pGroupConfig);
  177. hRc = InitMembers( pGroupConfig );
  178. if (FAILED(hRc))
  179. {
  180. DebugPrintEx(
  181. DEBUG_ERR,
  182. _T("Failed to InitMembers"));
  183. //NodeMsgBox done by called func.
  184. goto Exit;
  185. }
  186. Exit:
  187. return hRc;
  188. }
  189. /*
  190. - CFaxOutboundRoutingGroupNode::InitMembers
  191. -
  192. * Purpose:
  193. * Private method to initiate members
  194. * Must be called after init of m_pParentNode
  195. *
  196. * Arguments:
  197. * [in] pGroupConfig - FAX_OUTBOUND_ROUTING_GROUP structure
  198. *
  199. * Return:
  200. * OLE error code
  201. */
  202. HRESULT CFaxOutboundRoutingGroupNode::InitMembers(PFAX_OUTBOUND_ROUTING_GROUP pGroupConfig)
  203. {
  204. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::InitMembers"));
  205. HRESULT hRc = S_OK;
  206. ATLASSERT(pGroupConfig);
  207. //
  208. // status and Icon
  209. //
  210. m_enumStatus = pGroupConfig->Status;
  211. InitIcons ();
  212. //
  213. // Device List
  214. //
  215. m_dwNumOfDevices = pGroupConfig->dwNumDevices;
  216. ATLASSERT(0 <= m_dwNumOfDevices);
  217. if (0 < m_dwNumOfDevices)
  218. {
  219. //if (NULL != m_dwNumOfDevices)
  220. //{
  221. // delete[] m_lpdwDeviceID;
  222. //}
  223. m_lpdwDeviceID = new DWORD[m_dwNumOfDevices];
  224. if (NULL == m_lpdwDeviceID)
  225. {
  226. DebugPrintEx(
  227. DEBUG_ERR,
  228. _T("Error allocating %ld device ids"),
  229. m_dwNumOfDevices);
  230. hRc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  231. goto Error;
  232. }
  233. memcpy(m_lpdwDeviceID, pGroupConfig->lpdwDevices, sizeof(DWORD)*m_dwNumOfDevices) ;
  234. }
  235. else
  236. {
  237. DebugPrintEx( DEBUG_MSG, _T("Device list found to be currrently empty."));
  238. //if (NULL != m_dwNumOfDevices)
  239. //{
  240. // delete[] m_lpdwDeviceID;
  241. //}
  242. m_lpdwDeviceID = NULL;
  243. }
  244. hRc = InitGroupName(pGroupConfig->lpctstrGroupName);
  245. if (FAILED(hRc))
  246. {
  247. goto Error;
  248. }
  249. ATLASSERT(S_OK == hRc);
  250. goto Exit;
  251. Error:
  252. ATLASSERT(S_OK != hRc);
  253. DebugPrintEx(
  254. DEBUG_ERR,
  255. _T("Failed to allocate string - out of memory"));
  256. ATLASSERT(NULL != m_pParentNode);
  257. if (NULL != m_pParentNode)
  258. {
  259. m_pParentNode->NodeMsgBox(IDS_MEMORY);
  260. }
  261. Exit:
  262. return (hRc);
  263. }
  264. /*
  265. - CFaxOutboundRoutingGroupNode::InitGroupName
  266. -
  267. * Purpose:
  268. * Init the display name and group name from given group name.
  269. * Displayed name may be changed to localized version if it is
  270. * the All Devices Group.
  271. *
  272. * Arguments:
  273. *
  274. * Return:
  275. * OLE error code
  276. */
  277. HRESULT CFaxOutboundRoutingGroupNode::InitGroupName(LPCTSTR lpctstrGroupName)
  278. {
  279. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::InitGroupName"));
  280. HRESULT hRc = S_OK;
  281. if ( 0 == wcscmp(ROUTING_GROUP_ALL_DEVICES, lpctstrGroupName))
  282. {
  283. //
  284. // Replace <all Devices> string with the localized string
  285. //
  286. if (!m_bstrDisplayName.LoadString(_Module.GetResourceInstance(),
  287. IDS_ALL_DEVICES) )
  288. {
  289. hRc = E_OUTOFMEMORY;
  290. goto Error;
  291. }
  292. }
  293. else
  294. {
  295. m_bstrDisplayName = lpctstrGroupName;
  296. if (!m_bstrDisplayName)
  297. {
  298. hRc = E_OUTOFMEMORY;
  299. goto Error;
  300. }
  301. }
  302. m_bstrGroupName = lpctstrGroupName;
  303. if (!m_bstrGroupName)
  304. {
  305. hRc = E_OUTOFMEMORY;
  306. goto Error;
  307. }
  308. ATLASSERT(S_OK == hRc);
  309. goto Exit;
  310. Error:
  311. ATLASSERT(S_OK != hRc);
  312. DebugPrintEx(
  313. DEBUG_ERR,
  314. _T("Failed to allocate string - out of memory"));
  315. //NodeMsgBox done by Caller func.
  316. Exit:
  317. return (hRc);
  318. }
  319. /*
  320. - CFaxOutboundRoutingGroupNode::GetResultPaneColInfo
  321. -
  322. * Purpose:
  323. * Return the text for specific column
  324. * Called for each column in the result pane
  325. *
  326. * Arguments:
  327. * [in] nCol - column number
  328. *
  329. * Return:
  330. * String to be displayed in the specific column
  331. */
  332. LPOLESTR CFaxOutboundRoutingGroupNode::GetResultPaneColInfo(int nCol)
  333. {
  334. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::GetResultPaneColInfo"));
  335. HRESULT hRc = S_OK;
  336. UINT idsStatus;
  337. int iCount;
  338. WCHAR buff[FXS_MAX_NUM_OF_DEVICES_LEN+1];
  339. m_buf.Empty();
  340. switch (nCol)
  341. {
  342. case 0:
  343. //
  344. // Name
  345. //
  346. if (!m_bstrDisplayName)
  347. {
  348. DebugPrintEx(
  349. DEBUG_ERR,
  350. TEXT("Null memeber BSTR - m_bstrGroupName."));
  351. goto Error;
  352. }
  353. else
  354. {
  355. return (m_bstrDisplayName);
  356. }
  357. case 1:
  358. //
  359. // Number of Devices
  360. //
  361. iCount = swprintf(buff, L"%ld", m_dwNumOfDevices);
  362. if( iCount <= 0 )
  363. {
  364. DebugPrintEx(
  365. DEBUG_ERR,
  366. TEXT("Fail to read member - m_dwNumOfDevices."));
  367. goto Error;
  368. }
  369. else
  370. {
  371. m_buf = buff;
  372. return (m_buf);
  373. }
  374. case 2:
  375. //
  376. // Status
  377. //
  378. idsStatus = GetStatusIDS(m_enumStatus);
  379. if ( FXS_IDS_STATUS_ERROR == idsStatus)
  380. {
  381. DebugPrintEx(
  382. DEBUG_ERR,
  383. TEXT("Invalid Status value or not supported status value."));
  384. goto Error;
  385. }
  386. else
  387. {
  388. if (!m_buf.LoadString(idsStatus))
  389. {
  390. hRc = E_OUTOFMEMORY;
  391. DebugPrintEx(
  392. DEBUG_ERR,
  393. TEXT("Out of memory. Failed to load status string."));
  394. goto Error;
  395. }
  396. return m_buf;
  397. }
  398. default:
  399. ATLASSERT(0); // "this number of column is not supported "
  400. return(L"");
  401. } // endswitch (nCol)
  402. Error:
  403. return(L"???");
  404. }
  405. /*
  406. - CFaxOutboundRoutingGroupNode::InsertColumns
  407. -
  408. * Purpose:
  409. * Adds columns to the default result pane.
  410. *
  411. * Arguments:
  412. * [in] pHeaderCtrl - IHeaderCtrl in the console-provided default result view pane
  413. *
  414. * Return:
  415. * OLE error code
  416. */
  417. HRESULT
  418. CFaxOutboundRoutingGroupNode::InsertColumns(IHeaderCtrl *pHeaderCtrl)
  419. {
  420. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::InsertColumns"));
  421. HRESULT hRc = S_OK;
  422. static ColumnsInfoInitData ColumnsInitData[] =
  423. {
  424. {IDS_OUTBOUND_DEVICES_COL1, FXS_WIDE_COLUMN_WIDTH},
  425. {IDS_OUTBOUND_DEVICES_COL2, AUTO_WIDTH},
  426. {IDS_OUTBOUND_DEVICES_COL3, AUTO_WIDTH},
  427. {IDS_OUTBOUND_DEVICES_COL4, AUTO_WIDTH},
  428. {LAST_IDS, 0}
  429. };
  430. hRc = m_ColsInfo.InsertColumnsIntoMMC(pHeaderCtrl,
  431. _Module.GetResourceInstance(),
  432. ColumnsInitData);
  433. CHECK_RETURN_VALUE_AND_PRINT_DEBUG (_T("m_ColsInfo.InsertColumnsIntoMMC"))
  434. Cleanup:
  435. return(hRc);
  436. }
  437. /*
  438. - CFaxOutboundRoutingGroupNode::PopulateResultChildrenList
  439. -
  440. * Purpose:
  441. * Create the FaxOutboundRoutingGroup device nodes
  442. *
  443. * Arguments:
  444. *
  445. * Return:
  446. * OLE error code
  447. */
  448. HRESULT CFaxOutboundRoutingGroupNode::PopulateResultChildrenList()
  449. {
  450. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::PopulateResultChildrenList"));
  451. HRESULT hRc = S_OK;
  452. BOOL fIsAllDevicesGroup = FALSE;
  453. CFaxOutboundRoutingDeviceNode * pDevice;
  454. if( 0 == wcscmp(ROUTING_GROUP_ALL_DEVICES, m_bstrGroupName) )
  455. {
  456. fIsAllDevicesGroup = TRUE;
  457. }
  458. for ( DWORD i=0; i< m_dwNumOfDevices; i++ )
  459. {
  460. pDevice = NULL;
  461. pDevice = new CFaxOutboundRoutingDeviceNode(this,
  462. m_pComponentData);
  463. if (!pDevice)
  464. {
  465. hRc = E_OUTOFMEMORY;
  466. NodeMsgBox(IDS_MEMORY);
  467. DebugPrintEx(
  468. DEBUG_ERR,
  469. TEXT("Out of memory. (hRc: %08X)"),
  470. hRc);
  471. goto Error;
  472. }
  473. else
  474. {
  475. //
  476. // Init parent node ptr, RPC structure,
  477. // members displayed name and icon
  478. //
  479. hRc = pDevice->Init( m_lpdwDeviceID[i],
  480. i+1,
  481. (UINT)m_dwNumOfDevices,
  482. this);
  483. if (FAILED(hRc))
  484. {
  485. if( ERROR_BAD_UNIT != HRESULT_CODE(hRc) )
  486. {
  487. DebugPrintEx(
  488. DEBUG_ERR,
  489. TEXT("Fail to add Device Node below Outbound Routing Group. (hRc: %08X)"),
  490. hRc);
  491. //NodeMsgBox done by called functions
  492. goto Error;
  493. }
  494. else
  495. {
  496. DebugPrintEx(
  497. DEBUG_MSG,
  498. TEXT("+++ +++ system can not find one device from the group. (hRc: %08X) +++ +++"),
  499. hRc);
  500. //Continue - user informed data reay
  501. //we will show the bad device
  502. hRc = S_OK;
  503. }
  504. }
  505. if( fIsAllDevicesGroup )
  506. {
  507. pDevice->MarkAsChildOfAllDevicesGroup();
  508. }
  509. hRc = this->AddChildToList(pDevice);
  510. if (FAILED(hRc))
  511. {
  512. DebugPrintEx(
  513. DEBUG_ERR,
  514. TEXT("Fail to add Device Node below Outbound Routing Group. (hRc: %08X)"),
  515. hRc);
  516. NodeMsgBox(IDS_FAIL_ADD_DEVICE);
  517. goto Error;
  518. }
  519. else
  520. {
  521. pDevice = NULL;
  522. }
  523. }
  524. }
  525. ATLASSERT(S_OK == hRc);
  526. //
  527. // Success ToPopulateAllDevices to allow
  528. // giving total number of devices to each device
  529. // when asked for reordering purposes
  530. //
  531. m_fSuccess = TRUE;
  532. goto Exit;
  533. Error:
  534. ATLASSERT(S_OK != hRc);
  535. if ( NULL != pDevice )
  536. {
  537. delete pDevice;
  538. pDevice = NULL;
  539. }
  540. //
  541. // Get rid of what we had.
  542. //
  543. {
  544. // Delete each node in the list of children
  545. int iSize = m_ResultChildrenList.GetSize();
  546. for (int j = 0; j < iSize; j++)
  547. {
  548. pDevice = (CFaxOutboundRoutingDeviceNode *)
  549. m_ResultChildrenList[j];
  550. delete pDevice;
  551. }
  552. // Empty the list
  553. m_ResultChildrenList.RemoveAll();
  554. // We no longer have a populated list.
  555. m_bResultChildrenListPopulated = FALSE;
  556. }
  557. Exit:
  558. return hRc;
  559. }
  560. /*
  561. - CFaxOutboundRoutingGroupNode::SetVerbs
  562. -
  563. * Purpose:
  564. * What verbs to enable/disable when this object is selected
  565. *
  566. * Arguments:
  567. * [in] pConsoleVerb - MMC ConsoleVerb interface
  568. *
  569. * Return:
  570. * OLE Error code
  571. */
  572. HRESULT CFaxOutboundRoutingGroupNode::SetVerbs(IConsoleVerb *pConsoleVerb)
  573. {
  574. HRESULT hRc = S_OK;
  575. //
  576. // Display verbs that we support:
  577. // 1. Delete
  578. // 2. Refresh
  579. //
  580. if(0 == wcscmp(ROUTING_GROUP_ALL_DEVICES, m_bstrGroupName) )
  581. {
  582. hRc = pConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, FALSE);
  583. hRc = pConsoleVerb->SetVerbState(MMC_VERB_DELETE, INDETERMINATE, TRUE);
  584. }
  585. else
  586. {
  587. hRc = pConsoleVerb->SetVerbState(MMC_VERB_DELETE, ENABLED, TRUE);
  588. }
  589. hRc = pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, TRUE);
  590. //
  591. // We want the default verb to be expand node children
  592. //
  593. hRc = pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  594. return hRc;
  595. }
  596. /*
  597. - CFaxOutboundRoutingGroupNode::OnRefresh
  598. -
  599. * Purpose:
  600. * Called when refreshing the object.
  601. *
  602. * Arguments:
  603. *
  604. * Return:
  605. * OLE error code
  606. */
  607. /* virtual */HRESULT
  608. CFaxOutboundRoutingGroupNode::OnRefresh(LPARAM arg,
  609. LPARAM param,
  610. IComponentData *pComponentData,
  611. IComponent * pComponent,
  612. DATA_OBJECT_TYPES type)
  613. {
  614. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::OnRefresh"));
  615. HRESULT hRc = S_OK;
  616. //
  617. // Refresh from server
  618. //
  619. hRc = RefreshFromRPC();
  620. if (FAILED(hRc))
  621. {
  622. //msg by called func.
  623. {
  624. hRc = m_pParentNode->DoRefresh();
  625. if ( FAILED(hRc) )
  626. {
  627. DebugPrintEx(
  628. DEBUG_ERR,
  629. _T("Fail to call parent node - Groups DoRefresh. (hRc: %08X)"),
  630. hRc);
  631. }
  632. return hRc;
  633. }
  634. }
  635. else
  636. {
  637. //
  638. // Update Group's icon by reselecting the group node.
  639. //
  640. hRc = RefreshNameSpaceNode();
  641. if (FAILED(hRc))
  642. {
  643. DebugPrintEx(
  644. DEBUG_ERR,
  645. TEXT("Fail to refresh the group node. (hRc: %08X)"),
  646. hRc);
  647. return hRc;
  648. }
  649. }
  650. //
  651. // Call the base class
  652. //
  653. hRc = CBaseFaxOutboundRoutingGroupNode::OnRefresh(arg,
  654. param,
  655. pComponentData,
  656. pComponent,
  657. type);
  658. if ( FAILED(hRc) )
  659. {
  660. DebugPrintEx(
  661. DEBUG_ERR,
  662. _T("Fail to call base class's OnRefresh. (hRc: %08X)"),
  663. hRc);
  664. int iRes;
  665. NodeMsgBox(IDS_FAIL2REFERESH_GROUP, MB_OK | MB_ICONERROR, &iRes);
  666. ATLASSERT(IDOK == iRes);
  667. ATLASSERT(m_pParentNode);
  668. if (IDOK == iRes)
  669. {
  670. hRc = m_pParentNode->DoRefresh();
  671. if ( FAILED(hRc) )
  672. {
  673. DebugPrintEx(
  674. DEBUG_ERR,
  675. _T("Fail to call parent node - Groups DoRefresh. (hRc: %08X)"),
  676. hRc);
  677. }
  678. }
  679. }
  680. return hRc;
  681. }
  682. /*
  683. - CFaxOutboundRoutingGroupNode::OnNewDevice
  684. -
  685. * Purpose:
  686. *
  687. *
  688. * Arguments:
  689. * [out] bHandled - Do we handle it?
  690. * [in] pRoot - The snapin object root base node
  691. *
  692. * Return:
  693. * OLE Error code
  694. */
  695. HRESULT
  696. CFaxOutboundRoutingGroupNode::OnNewDevice(bool &bHandled, CSnapInObjectRootBase *pRoot)
  697. {
  698. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::OnNewGroup"));
  699. HRESULT hRc = S_OK;
  700. INT_PTR rc = IDOK;
  701. CDlgNewFaxOutboundDevice DlgNewDevice(((CFaxServerNode *)GetRootNode())->GetFaxServer());
  702. //
  703. // Dialog to add device
  704. //
  705. hRc = DlgNewDevice.InitDevices(m_dwNumOfDevices, m_lpdwDeviceID, m_bstrGroupName);
  706. if (FAILED(hRc))
  707. {
  708. NodeMsgBox(IDS_FAIL2OPEN_DLG);
  709. return hRc;
  710. }
  711. rc = DlgNewDevice.DoModal();
  712. if (rc != IDOK)
  713. {
  714. goto Cleanup;
  715. }
  716. //
  717. // Refresh the data
  718. // - Get newdata from RPC
  719. // - init members and
  720. // - Set icons
  721. //
  722. hRc = RefreshFromRPC();
  723. if (FAILED(hRc))
  724. {
  725. //msg by called func.
  726. return hRc;
  727. }
  728. //
  729. // Refresh result pane view
  730. //
  731. DoRefresh(pRoot);
  732. //
  733. // This will force MMC to redraw the scope group node
  734. //
  735. hRc = RefreshNameSpaceNode();
  736. if (FAILED(hRc))
  737. {
  738. DebugPrintEx(
  739. DEBUG_ERR,
  740. TEXT("Fail to RefreshNameSpaceNode. (hRc: %08X)"),
  741. hRc);
  742. goto Error;
  743. }
  744. ATLASSERT( S_OK == hRc);
  745. goto Cleanup;
  746. Error:
  747. ATLASSERT( S_OK != hRc);
  748. NodeMsgBox(IDS_FAIL2UPDATEITEM_GROUP);
  749. Cleanup:
  750. return hRc;
  751. }
  752. /*
  753. - CFaxOutboundRoutingGroupNode::DoRefresh
  754. -
  755. * Purpose:
  756. * Refresh the view
  757. *
  758. * Arguments:
  759. * [in] pRoot - The root node
  760. *
  761. * Return:
  762. * OLE Error code
  763. */
  764. HRESULT
  765. CFaxOutboundRoutingGroupNode::DoRefresh(CSnapInObjectRootBase *pRoot)
  766. {
  767. CComPtr<IConsole> spConsole;
  768. //
  769. // Repopulate childs
  770. //
  771. RepopulateResultChildrenList();
  772. if (pRoot)
  773. {
  774. //
  775. // Get the console pointer
  776. //
  777. ATLASSERT(pRoot->m_nType == 1 || pRoot->m_nType == 2);
  778. if (pRoot->m_nType == 1)
  779. {
  780. //
  781. // m_ntype == 1 means the IComponentData implementation
  782. //
  783. CSnapin *pCComponentData = static_cast<CSnapin *>(pRoot);
  784. spConsole = pCComponentData->m_spConsole;
  785. }
  786. else
  787. {
  788. //
  789. // m_ntype == 2 means the IComponent implementation
  790. //
  791. CSnapinComponent *pCComponent = static_cast<CSnapinComponent *>(pRoot);
  792. spConsole = pCComponent->m_spConsole;
  793. }
  794. }
  795. else
  796. {
  797. ATLASSERT(m_pComponentData);
  798. spConsole = m_pComponentData->m_spConsole;
  799. }
  800. ATLASSERT(spConsole);
  801. spConsole->UpdateAllViews(NULL, NULL, NULL);
  802. return S_OK;
  803. }
  804. /*
  805. - CFaxOutboundRoutingGroupNode::GetStatusIDS
  806. -
  807. * Purpose:
  808. * Transslate Status to IDS.
  809. *
  810. * Arguments:
  811. *
  812. * [in] enumStatus - unsigned int with the menu IDM value
  813. *
  814. * Return:
  815. * IDS of related status message
  816. */
  817. UINT CFaxOutboundRoutingGroupNode::GetStatusIDS(FAX_ENUM_GROUP_STATUS enumStatus)
  818. {
  819. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::GetStatusIDS"));
  820. switch (enumStatus)
  821. {
  822. case FAX_GROUP_STATUS_ALL_DEV_VALID:
  823. return IDS_STATUS_GROUP_ALL_DEV_VALID;
  824. case FAX_GROUP_STATUS_EMPTY:
  825. return IDS_STATUS_GROUP_EMPTY;
  826. case FAX_GROUP_STATUS_ALL_DEV_NOT_VALID:
  827. return IDS_STATUS_GROUP_ALLDEVICESINVALID;
  828. case FAX_GROUP_STATUS_SOME_DEV_NOT_VALID:
  829. return IDS_STATUS_GROUP_SOMEDEVICESINVALID;
  830. default:
  831. ATLASSERT(0); // "this enumStatus is not supported "
  832. return(FXS_IDS_STATUS_ERROR); //currently 999
  833. } // endswitch (enumStatus)
  834. }
  835. /*
  836. - CFaxOutboundRoutingGroupNode::InitIcons
  837. -
  838. * Purpose:
  839. * Private method that initiate icons
  840. * due to the status member state.
  841. *
  842. * Arguments:
  843. * No.
  844. *
  845. * Return:
  846. * No.
  847. */
  848. void CFaxOutboundRoutingGroupNode::InitIcons ()
  849. {
  850. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::InitIcons"));
  851. switch (m_enumStatus)
  852. {
  853. case FAX_GROUP_STATUS_ALL_DEV_VALID:
  854. SetIcons(IMAGE_FOLDER_CLOSE, IMAGE_FOLDER_OPEN);
  855. return;
  856. case FAX_GROUP_STATUS_SOME_DEV_NOT_VALID:
  857. SetIcons(IMAGE_GROUP_WARN_CLOSE, IMAGE_GROUP_WARN_OPEN);
  858. return;
  859. case FAX_GROUP_STATUS_EMPTY:
  860. case FAX_GROUP_STATUS_ALL_DEV_NOT_VALID:
  861. SetIcons(IMAGE_GROUP_ERROR_CLOSE, IMAGE_GROUP_ERROR_OPEN);
  862. return;
  863. default:
  864. ATLASSERT(FALSE); // "this enumStatus is not supported "
  865. SetIcons(IMAGE_GROUP_ERROR_CLOSE, IMAGE_GROUP_ERROR_OPEN);
  866. return; //currently 999
  867. }
  868. }
  869. /*
  870. - CFaxOutboundRoutingGroupNode::OnDelete
  871. -
  872. * Purpose:
  873. * Called when deleting this node
  874. *
  875. * Arguments:
  876. *
  877. * Return:
  878. * OLE error code
  879. */
  880. HRESULT CFaxOutboundRoutingGroupNode::OnDelete(
  881. LPARAM arg,
  882. LPARAM param,
  883. IComponentData *pComponentData,
  884. IComponent *pComponent,
  885. DATA_OBJECT_TYPES type,
  886. BOOL fSilent/* = FALSE*/
  887. )
  888. {
  889. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::OnDelete"));
  890. UNREFERENCED_PARAMETER (arg);
  891. UNREFERENCED_PARAMETER (param);
  892. UNREFERENCED_PARAMETER (pComponentData);
  893. UNREFERENCED_PARAMETER (pComponent);
  894. UNREFERENCED_PARAMETER (type);
  895. CComBSTR bstrName;
  896. HRESULT hRc = S_OK;
  897. //
  898. // Are you sure?
  899. //
  900. if (! fSilent)
  901. {
  902. //
  903. // 1. Use pConsole as owner of the message box
  904. //
  905. int res;
  906. NodeMsgBox(IDS_CONFIRM, MB_YESNO | MB_ICONWARNING, &res);
  907. if (IDNO == res)
  908. {
  909. goto Cleanup;
  910. }
  911. }
  912. //
  913. // Group name
  914. //
  915. if ( !m_bstrGroupName || L"???" == m_bstrGroupName)
  916. {
  917. NodeMsgBox(IDS_INVALID_GROUP_NAME);
  918. goto Cleanup;
  919. }
  920. bstrName = m_bstrGroupName;
  921. //
  922. // Delete it
  923. //
  924. ATLASSERT(m_pParentNode);
  925. hRc = m_pParentNode->DeleteGroup(bstrName, this);
  926. if ( FAILED(hRc) )
  927. {
  928. goto Cleanup;
  929. }
  930. Cleanup:
  931. return hRc;
  932. }
  933. /*
  934. - CFaxOutboundRoutingGroupNode::ChangeDeviceOrder
  935. -
  936. * Purpose:
  937. * This func moves up or down specific device in the group order
  938. *
  939. * Arguments:
  940. * [in] dwNewOrder - specifies the new order +1 /-1 inrelative to current order.
  941. * [in] dwDeviceID - Device ID
  942. * [in] pChildNode - the device node object.
  943. *
  944. * Return:
  945. * OLE error code
  946. */
  947. HRESULT CFaxOutboundRoutingGroupNode::ChangeDeviceOrder(DWORD dwOrder, DWORD dwNewOrder, DWORD dwDeviceID, CSnapInObjectRootBase *pRoot)
  948. {
  949. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::ChangeDeviceOrder"));
  950. HRESULT hRc = S_OK;
  951. DWORD ec = ERROR_SUCCESS;
  952. CFaxServer * pFaxServer = NULL;
  953. int iIndex, iNewIndex;
  954. CFaxOutboundRoutingDeviceNode* tmpChildNode;
  955. CComPtr<IConsole> spConsole;
  956. //
  957. // Validity asserts
  958. //
  959. ATLASSERT((dwNewOrder-1)< m_dwNumOfDevices);
  960. ATLASSERT((dwNewOrder-1)>= 0);
  961. ATLASSERT((dwOrder-1)< m_dwNumOfDevices);
  962. ATLASSERT((dwOrder-1)>= 0);
  963. ATLASSERT( ( (dwOrder-1)-(dwNewOrder-1) == 1)
  964. || ( (dwOrder-1)-(dwNewOrder-1) == -1) );
  965. //
  966. // init swaped indexes
  967. //
  968. iIndex = (int)(dwOrder-1);
  969. iNewIndex = (int)(dwNewOrder-1);
  970. //
  971. // RPC change Order
  972. //
  973. pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  974. ATLASSERT(pFaxServer);
  975. if (!pFaxServer->GetFaxServerHandle())
  976. {
  977. ec= GetLastError();
  978. DebugPrintEx(
  979. DEBUG_ERR,
  980. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  981. ec);
  982. goto Error;
  983. }
  984. if (!FaxSetDeviceOrderInGroup(
  985. pFaxServer->GetFaxServerHandle(),
  986. m_bstrGroupName/*lpctstrGroupName*/,
  987. dwDeviceID,
  988. dwNewOrder) )
  989. {
  990. ec = GetLastError();
  991. DebugPrintEx(
  992. DEBUG_ERR,
  993. _T("Fail to Set new order. (ec: %ld)"),
  994. ec);
  995. if (IsNetworkError(ec))
  996. {
  997. DebugPrintEx(
  998. DEBUG_ERR,
  999. _T("Network Error was found. (ec: %ld)"),
  1000. ec);
  1001. pFaxServer->Disconnect();
  1002. }
  1003. goto Error;
  1004. }
  1005. else // Success of RPC -> Now to MMC
  1006. {
  1007. //
  1008. // Local swap
  1009. //
  1010. tmpChildNode = m_ResultChildrenList[iIndex];
  1011. m_ResultChildrenList[iIndex] = m_ResultChildrenList[iNewIndex];
  1012. m_ResultChildrenList[iNewIndex] = tmpChildNode;
  1013. m_ResultChildrenList[iIndex]->SetOrder((UINT)iIndex+1);
  1014. m_ResultChildrenList[iNewIndex]->SetOrder((UINT)iNewIndex+1);
  1015. //
  1016. // Get console
  1017. //
  1018. if (pRoot)
  1019. {
  1020. //
  1021. // Get the console pointer
  1022. //
  1023. ATLASSERT(pRoot->m_nType == 1 || pRoot->m_nType == 2);
  1024. if (pRoot->m_nType == 1)
  1025. {
  1026. //
  1027. // m_ntype == 1 means the IComponentData implementation
  1028. //
  1029. CSnapin *pCComponentData = static_cast<CSnapin *>(pRoot);
  1030. spConsole = pCComponentData->m_spConsole;
  1031. }
  1032. else
  1033. {
  1034. //
  1035. // m_ntype == 2 means the IComponent implementation
  1036. //
  1037. CSnapinComponent *pCComponent = static_cast<CSnapinComponent *>(pRoot);
  1038. spConsole = pCComponent->m_spConsole;
  1039. }
  1040. }
  1041. else
  1042. {
  1043. ATLASSERT(m_pComponentData);
  1044. spConsole = m_pComponentData->m_spConsole;
  1045. }
  1046. ATLASSERT(spConsole);
  1047. //
  1048. // UpdateAllViews
  1049. //
  1050. spConsole->UpdateAllViews(NULL, (LPARAM)this, NULL);
  1051. //
  1052. // Reselect the moved item in his new place
  1053. //
  1054. m_ResultChildrenList[iNewIndex]->ReselectItemInView(spConsole);
  1055. }
  1056. ATLASSERT(S_OK == hRc);
  1057. DebugPrintEx( DEBUG_MSG,
  1058. _T("Succeed to set devices new order for Outbound Routing group."));
  1059. goto Exit;
  1060. Error:
  1061. ATLASSERT(ERROR_SUCCESS != ec);
  1062. hRc = HRESULT_FROM_WIN32(ec);
  1063. ATLASSERT(NULL != m_pParentNode);
  1064. NodeMsgBox(GetFaxServerErrorMsg(ec));
  1065. Exit:
  1066. return hRc;
  1067. }
  1068. /*
  1069. - CFaxOutboundRoutingGroupNode::SetNewDeviceList
  1070. -
  1071. * Purpose:
  1072. * To assign new device list to group.
  1073. *
  1074. * Arguments:
  1075. * [in] lpdwNewDeviceId - the new device ID list
  1076. *
  1077. * Return:
  1078. * OLE error code
  1079. */
  1080. HRESULT CFaxOutboundRoutingGroupNode::SetNewDeviceList(LPDWORD lpdwNewDeviceID)
  1081. {
  1082. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::SetNewDeviceLists"));
  1083. HRESULT hRc = S_OK;
  1084. DWORD ec = ERROR_SUCCESS;
  1085. CFaxServer * pFaxServer;
  1086. FAX_OUTBOUND_ROUTING_GROUP FaxGroupConfig;
  1087. //
  1088. // init the structure's fields and insert the new DeviceIdList
  1089. //
  1090. ZeroMemory (&FaxGroupConfig, sizeof(FAX_OUTBOUND_ROUTING_GROUP));
  1091. FaxGroupConfig.dwSizeOfStruct = sizeof(FAX_OUTBOUND_ROUTING_GROUP);
  1092. FaxGroupConfig.lpctstrGroupName = m_bstrGroupName;
  1093. FaxGroupConfig.dwNumDevices = m_dwNumOfDevices - 1;
  1094. FaxGroupConfig.Status = m_enumStatus;
  1095. FaxGroupConfig.lpdwDevices = lpdwNewDeviceID;
  1096. //
  1097. // get RPC Handle
  1098. //
  1099. pFaxServer = ((CFaxServerNode *)GetRootNode())->GetFaxServer();
  1100. ATLASSERT(pFaxServer);
  1101. if (!pFaxServer->GetFaxServerHandle())
  1102. {
  1103. ec= GetLastError();
  1104. DebugPrintEx(
  1105. DEBUG_ERR,
  1106. _T("Failed to GetFaxServerHandle. (ec: %ld)"),
  1107. ec);
  1108. goto Error;
  1109. }
  1110. //
  1111. // Set Config
  1112. //
  1113. if (!FaxSetOutboundGroup(
  1114. pFaxServer->GetFaxServerHandle(),
  1115. &FaxGroupConfig))
  1116. {
  1117. ec = GetLastError();
  1118. DebugPrintEx(
  1119. DEBUG_ERR,
  1120. _T("Fail to set the group with new device list. (ec: %ld)"),
  1121. ec);
  1122. if (IsNetworkError(ec))
  1123. {
  1124. DebugPrintEx(
  1125. DEBUG_ERR,
  1126. _T("Network Error was found. (ec: %ld)"),
  1127. ec);
  1128. pFaxServer->Disconnect();
  1129. }
  1130. goto Error;
  1131. }
  1132. ATLASSERT(ERROR_SUCCESS == ec);
  1133. DebugPrintEx( DEBUG_MSG,
  1134. _T("Succeed to set device configuration."));
  1135. goto Exit;
  1136. Error:
  1137. ATLASSERT(ERROR_SUCCESS != ec);
  1138. hRc = HRESULT_FROM_WIN32(ec);
  1139. ATLASSERT(NULL != m_pParentNode);
  1140. NodeMsgBox(GetFaxServerErrorMsg(ec));
  1141. Exit:
  1142. return(hRc);
  1143. }
  1144. /*
  1145. - CFaxOutboundRoutingGroupNode::DeleteDevice
  1146. -
  1147. * Purpose:
  1148. * Delete Device from the group
  1149. *
  1150. * Arguments:
  1151. * [in] dwDeviceID - The device ID
  1152. * [in] pChildNode - The node to be deleted
  1153. *
  1154. * Return:
  1155. * OLE Error code
  1156. */
  1157. HRESULT
  1158. CFaxOutboundRoutingGroupNode::DeleteDevice(DWORD dwDeviceIdToRemove, CFaxOutboundRoutingDeviceNode *pChildNode)
  1159. {
  1160. DEBUG_FUNCTION_NAME(_T("CFaxOutboundRoutingDeviceNode::DeleteDevice"));
  1161. HRESULT hRc = S_OK;
  1162. DWORD ec = ERROR_SUCCESS;
  1163. DWORD dwIndex;
  1164. DWORD dwNewIndex;
  1165. int j;
  1166. LPDWORD lpdwNewDeviceID = NULL;
  1167. LPDWORD lpdwTmp;
  1168. ATLASSERT( 0 < m_dwNumOfDevices);
  1169. //
  1170. // Step 1: create new DeviceID array
  1171. //
  1172. //
  1173. // prepare for loop
  1174. //
  1175. lpdwTmp = &m_lpdwDeviceID[0];
  1176. if ((m_dwNumOfDevices - 1) > 0 )
  1177. {
  1178. lpdwNewDeviceID = new DWORD[m_dwNumOfDevices - 1];
  1179. if (NULL == lpdwNewDeviceID)
  1180. {
  1181. DebugPrintEx(
  1182. DEBUG_ERR,
  1183. _T("Error allocating %ld device ids"),
  1184. m_dwNumOfDevices - 1);
  1185. hRc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  1186. goto Error;
  1187. }
  1188. }
  1189. dwNewIndex = 0;
  1190. for ( dwIndex = 0; dwIndex < m_dwNumOfDevices; dwIndex++, lpdwTmp++)
  1191. {
  1192. //
  1193. // Safty check for last itaration
  1194. //
  1195. if ( dwNewIndex == (m_dwNumOfDevices-1) )
  1196. {
  1197. if ( dwDeviceIdToRemove != *lpdwTmp)
  1198. {
  1199. //unexpected error
  1200. DebugPrintEx( DEBUG_ERR,
  1201. _T("Unexpected error - The device was not found."));
  1202. ATLASSERT(0);
  1203. hRc = S_FALSE;
  1204. goto Error;
  1205. }
  1206. else //Device to remove found as the last one. Do nothing.
  1207. {
  1208. break;
  1209. }
  1210. }
  1211. //
  1212. // main operation
  1213. //
  1214. if ( dwDeviceIdToRemove != *lpdwTmp)
  1215. {
  1216. lpdwNewDeviceID[dwNewIndex] = *lpdwTmp;
  1217. dwNewIndex++;
  1218. }
  1219. // else Found the device to delete. do noting.
  1220. }
  1221. //
  1222. // Step 2: Insert the new device ID array to Group (via RPC)
  1223. //
  1224. //
  1225. // a) Call to Rpc Func.
  1226. //
  1227. hRc = SetNewDeviceList(lpdwNewDeviceID);
  1228. if (FAILED(hRc))
  1229. {
  1230. DebugPrintEx(
  1231. DEBUG_ERR,
  1232. _T("Fail to set the group with new device list. (RC: %0X8)"),
  1233. hRc);
  1234. goto Error;
  1235. }
  1236. //
  1237. // b) Update Group class relevant members and the icon
  1238. //
  1239. // 0) Clear old DeviceID array
  1240. if (m_dwNumOfDevices > 0 )
  1241. {
  1242. delete[] m_lpdwDeviceID;
  1243. m_lpdwDeviceID = NULL;
  1244. }
  1245. // 1) update m_dwNumOfDevices
  1246. --m_dwNumOfDevices;
  1247. // 2) update m_lpdwDeviceID
  1248. if (m_dwNumOfDevices > 0 )
  1249. {
  1250. m_lpdwDeviceID = new DWORD[m_dwNumOfDevices];
  1251. if (NULL == m_lpdwDeviceID)
  1252. {
  1253. DebugPrintEx(
  1254. DEBUG_ERR,
  1255. _T("Error allocating %ld device ids"),
  1256. m_dwNumOfDevices);
  1257. hRc = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  1258. goto Error;
  1259. }
  1260. memcpy(m_lpdwDeviceID , lpdwNewDeviceID, sizeof(DWORD)*m_dwNumOfDevices) ;
  1261. }
  1262. // 3) update icon
  1263. if ( 0 == m_dwNumOfDevices)
  1264. {
  1265. m_enumStatus = FAX_GROUP_STATUS_EMPTY;
  1266. InitIcons();
  1267. }
  1268. //
  1269. // Step 3: Update MMC views
  1270. //
  1271. //
  1272. // a) Remove Device from MMC result pane
  1273. //
  1274. ATLASSERT(pChildNode);
  1275. hRc = RemoveChild(pChildNode);
  1276. if (FAILED(hRc))
  1277. {
  1278. DebugPrintEx(
  1279. DEBUG_ERR,
  1280. TEXT("Fail to remove Device from MMC views. (hRc: %08X)"),
  1281. hRc);
  1282. goto Error;
  1283. }
  1284. //
  1285. // - Call the Device class destructor
  1286. //
  1287. delete pChildNode;
  1288. //
  1289. // b) Update Order in the rest devices
  1290. //
  1291. ATLASSERT( m_ResultChildrenList.GetSize() == (int)m_dwNumOfDevices);
  1292. for ( j = 0; j < (int)m_dwNumOfDevices; j++)
  1293. {
  1294. m_ResultChildrenList[j]->SetOrder((UINT)j+1, (UINT)m_dwNumOfDevices);
  1295. }
  1296. //
  1297. // c) Update the group views and the scope pane node itself
  1298. //
  1299. ATLASSERT( m_pComponentData != NULL );
  1300. ATLASSERT( m_pComponentData->m_spConsole != NULL );
  1301. hRc = m_pComponentData->m_spConsole->UpdateAllViews( NULL, NULL, NULL);
  1302. if (FAILED(hRc))
  1303. {
  1304. DebugPrintEx( DEBUG_ERR,
  1305. _T("Unexpected error - Fail to UpdateAllViews."));
  1306. NodeMsgBox(IDS_FAIL2UPDATEITEM_GROUP);
  1307. goto Exit;
  1308. }
  1309. if ( 0 == m_dwNumOfDevices)
  1310. {
  1311. //
  1312. // This will force MMC to redraw scope node
  1313. //
  1314. hRc = RefreshNameSpaceNode();
  1315. if (FAILED(hRc))
  1316. {
  1317. DebugPrintEx(
  1318. DEBUG_ERR,
  1319. TEXT("Fail to RefreshNameSpaceNode. (hRc: %08X)"),
  1320. hRc);
  1321. goto Error;
  1322. }
  1323. }
  1324. ATLASSERT(S_OK == hRc);
  1325. DebugPrintEx( DEBUG_MSG,
  1326. _T("The device was removed successfully."));
  1327. goto Exit;
  1328. Error:
  1329. NodeMsgBox(IDS_FAIL_TO_REMOVE_DEVICE);
  1330. Exit:
  1331. return hRc;
  1332. }
  1333. /*
  1334. - CFaxOutboundRoutingGroupNode::UpdateMenuState
  1335. -
  1336. * Purpose:
  1337. * Overrides the ATL CSnapInItemImpl::UpdateMenuState
  1338. * which only have one line inside it "return;"
  1339. * This function implements the grayed\ungrayed view for the
  1340. * the Enable and the Disable menus.
  1341. *
  1342. * Arguments:
  1343. *
  1344. * [in] id - unsigned int with the menu IDM value
  1345. * [out] pBuf - string
  1346. * [out] flags - pointer to flags state combination unsigned int
  1347. *
  1348. * Return:
  1349. * no return value - void function
  1350. */
  1351. void CFaxOutboundRoutingGroupNode::UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  1352. {
  1353. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::UpdateMenuState"));
  1354. UNREFERENCED_PARAMETER (pBuf);
  1355. if (IDM_NEW_DEVICES == id)
  1356. {
  1357. if( 0 == wcscmp(ROUTING_GROUP_ALL_DEVICES, m_bstrGroupName) )
  1358. {
  1359. *flags = MF_GRAYED;
  1360. }
  1361. else
  1362. {
  1363. *flags = MF_ENABLED;
  1364. }
  1365. }
  1366. return;
  1367. }
  1368. /*
  1369. - CFaxOutboundRoutingGroupNode::RefreshNameSpaceNode
  1370. -
  1371. * Purpose:
  1372. * Refresh the NameSpace fields of the node.
  1373. *
  1374. * Arguments:
  1375. *
  1376. * Return:
  1377. * OLE error code
  1378. */
  1379. HRESULT CFaxOutboundRoutingGroupNode::RefreshNameSpaceNode()
  1380. {
  1381. DEBUG_FUNCTION_NAME( _T("CFaxOutboundRoutingGroupNode::RefreshNameSpaceNode"));
  1382. HRESULT hRc = S_OK;
  1383. ATLASSERT( m_pComponentData != NULL );
  1384. ATLASSERT( m_pComponentData->m_spConsole != NULL );
  1385. CComPtr<IConsole> spConsole;
  1386. spConsole = m_pComponentData->m_spConsole;
  1387. CComQIPtr<IConsoleNameSpace,&IID_IConsoleNameSpace> spNamespace( spConsole );
  1388. SCOPEDATAITEM* pScopeData;
  1389. //
  1390. // Get the updated SCOPEDATAITEM
  1391. //
  1392. hRc = GetScopeData( &pScopeData );
  1393. if (FAILED(hRc))
  1394. {
  1395. DebugPrintEx(
  1396. DEBUG_ERR,
  1397. TEXT("Fail to get pScopeData. (hRc: %08X)"),
  1398. hRc);
  1399. goto Error;
  1400. }
  1401. //
  1402. // This will force MMC to redraw the scope group node
  1403. //
  1404. hRc = spNamespace->SetItem( pScopeData );
  1405. if (FAILED(hRc))
  1406. {
  1407. DebugPrintEx(
  1408. DEBUG_ERR,
  1409. TEXT("Fail to set Item pScopeData. (hRc: %08X)"),
  1410. hRc);
  1411. goto Error;
  1412. }
  1413. ATLASSERT( S_OK != hRc);
  1414. goto Exit;
  1415. Error:
  1416. NodeMsgBox(IDS_FAIL2REFRESH_GROUP);
  1417. Exit:
  1418. return hRc;
  1419. }
  1420. /*
  1421. +
  1422. + CFaxOutboundRoutingGroupNode::OnShowContextHelp
  1423. *
  1424. * Purpose:
  1425. * Overrides CSnapinNode::OnShowContextHelp.
  1426. *
  1427. * Arguments:
  1428. *
  1429. * Return:
  1430. - OLE error code
  1431. -
  1432. */
  1433. HRESULT CFaxOutboundRoutingGroupNode::OnShowContextHelp(
  1434. IDisplayHelp* pDisplayHelp, LPOLESTR helpFile)
  1435. {
  1436. return DisplayContextHelp(pDisplayHelp, helpFile, HLP_GROUPS);
  1437. }
  1438. ///////////////////////////////////////////////////////////////////