Source code of Windows XP (NT5)
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.

2289 lines
59 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. AcsHand.cpp
  7. Root node information (the root node is not displayed
  8. in the MMC framework but contains information such as
  9. all of the subnodes in this snapin).
  10. FILE HISTORY:
  11. 11/05/97 Wei Jiang Created
  12. */
  13. #include "stdafx.h"
  14. #include <secext.h>
  15. #include <objsel.h>
  16. #include "acs.h"
  17. #include "acshand.h"
  18. #include "util.h"
  19. #include "statsdlg.h"
  20. #include "modeless.h"
  21. #include "resource.h"
  22. #include "helper.h"
  23. #include "proppage.h"
  24. #include "acsadmin.h"
  25. #include "resource.h"
  26. #include "acscomp.h"
  27. #include "acsdata.h"
  28. #include "newsub.h"
  29. #include "pggen.h"
  30. #include "pgsrvs.h"
  31. #include "pgsbm.h"
  32. #include "pglog.h"
  33. // property pages
  34. #include "pgpolicy.h" // traffic page for ACSPolicy
  35. #include "ncglobal.h" // network console global defines
  36. // const TCHAR g_szDefaultHelpTopic[] = _T("\\help\\QOSConcepts.chm::/acs_usingTN.htm");
  37. const TCHAR g_szDefaultHelpTopic[] = _T("\\help\\QOSconcepts.chm::/sag_ACStopnode.htm");
  38. UINT g_col_strid_name[] = {IDS_NAME, 0};
  39. int g_col_width_name[] = {200, AUTO_WIDTH};
  40. UINT g_col_strid_name_type[] = {IDS_NAME, IDS_TYPE, 0};
  41. int g_col_width_name_type[] = {200, 75, AUTO_WIDTH};
  42. UINT g_col_strid_name_type_desc[] = {IDS_NAME, IDS_TYPE, IDS_DESC, 0};
  43. int g_col_width_name_type_desc[] = {200, 75, 250, AUTO_WIDTH};
  44. UINT g_col_strid_policy[] = {IDS_COL_POLICY_APPLIES_TO, IDS_COL_POLICY_DIRECTION, IDS_COL_POLICY_SERVICE_LEVEL, IDS_COL_POLICY_DATARATE, IDS_COL_POLICY_PEAKRATE, 0};
  45. int g_col_width_policy[] = {150, 100, 100, 50, 50, AUTO_WIDTH};
  46. const UINT g_col_count_policy = sizeof(g_col_strid_policy)/sizeof(UINT) - 1;
  47. // the date rate and peak rate do not make sense any more, since they are related to service type
  48. //UINT g_col_strid_subnet[] = {IDS_COL_SUBNET_NAME, IDS_COL_SUBNET_DESC, IDS_COL_SUBNET_DATARATE, IDS_COL_SUBNET_PEAKRATE, 0};
  49. //int g_col_width_subnet[] = {120, 150, 50, 50, AUTO_WIDTH};
  50. UINT g_col_strid_subnet[] = {IDS_COL_SUBNET_NAME, IDS_COL_SUBNET_DESC, 0};
  51. int g_col_width_subnet[] = {120, 150, AUTO_WIDTH};
  52. const UINT g_col_count_subnet = sizeof(g_col_strid_subnet)/sizeof(UINT) - 1;
  53. // keep a public map of MMC verbs
  54. const MMC_CONSOLE_VERB g_mmc_verbs[ACS_TOTAL_MMC_VERBS] =
  55. {
  56. MMC_VERB_OPEN,
  57. MMC_VERB_COPY,
  58. MMC_VERB_PASTE,
  59. MMC_VERB_DELETE,
  60. MMC_VERB_PROPERTIES,
  61. MMC_VERB_RENAME,
  62. MMC_VERB_REFRESH,
  63. MMC_VERB_PRINT
  64. };
  65. // verb state with no new menu, no property page
  66. MMC_BUTTON_STATE g_verbs_all_hiden[ACS_TOTAL_MMC_VERBS] =
  67. {
  68. HIDDEN, // MMC_VERB_OPEN,
  69. HIDDEN, // MMC_VERB_COPY,
  70. HIDDEN, // MMC_VERB_PASTE,
  71. HIDDEN, // MMC_VERB_DELETE,
  72. HIDDEN, // MMC_VERB_PROPERTIES,
  73. HIDDEN, // MMC_VERB_RENAME,
  74. HIDDEN, // MMC_VERB_REFRESH,
  75. HIDDEN // MMC_VERB_PRINT
  76. };
  77. // verb state with property page, delete, rename enabled
  78. MMC_BUTTON_STATE g_verbs_property_delete[ACS_TOTAL_MMC_VERBS] =
  79. {
  80. HIDDEN, // MMC_VERB_OPEN,
  81. HIDDEN, // MMC_VERB_COPY,
  82. HIDDEN, // MMC_VERB_PASTE,
  83. ENABLED, // MMC_VERB_DELETE,
  84. ENABLED, // MMC_VERB_PROPERTIES,
  85. HIDDEN, // MMC_VERB_RENAME,
  86. HIDDEN, // MMC_VERB_REFRESH,
  87. HIDDEN // MMC_VERB_PRINT
  88. };
  89. // Container with no property
  90. MMC_BUTTON_STATE g_verbs_property_refresh[ACS_TOTAL_MMC_VERBS] =
  91. {
  92. HIDDEN, // MMC_VERB_OPEN,
  93. HIDDEN, // MMC_VERB_COPY,
  94. HIDDEN, // MMC_VERB_PASTE,
  95. HIDDEN, // MMC_VERB_DELETE,
  96. ENABLED, // MMC_VERB_PROPERTIES,
  97. HIDDEN, // MMC_VERB_RENAME,
  98. ENABLED, // MMC_VERB_REFRESH,
  99. HIDDEN // MMC_VERB_PRINT
  100. };
  101. // Container with property
  102. MMC_BUTTON_STATE g_verbs_refresh[ACS_TOTAL_MMC_VERBS] =
  103. {
  104. HIDDEN, // MMC_VERB_OPEN,
  105. HIDDEN, // MMC_VERB_COPY,
  106. HIDDEN, // MMC_VERB_PASTE,
  107. HIDDEN, // MMC_VERB_DELETE,
  108. HIDDEN, // MMC_VERB_PROPERTIES,
  109. HIDDEN, // MMC_VERB_RENAME,
  110. ENABLED, // MMC_VERB_REFRESH,
  111. HIDDEN // MMC_VERB_PRINT
  112. };
  113. // context menu for new
  114. const UINT g_new_menus_newsub[] = {IDS_NEWSUBNET, 0};
  115. const UINT g_new_menus_policy[] = {IDS_NEWPOLICY, 0};
  116. const UINT g_menus_subnet[] = {IDS_NEWPOLICY, IDS_DELETESUBNET, 0};
  117. // const UINT g_new_menus_profile[] = {IDS_NEWPROFILE, 0};
  118. // static string IDs for strings
  119. const UINT g_strid_root[]= { IDS_ACSROOT, 0};
  120. const UINT g_strid_global[]= { IDS_GLOBAL, 0};
  121. /*
  122. const UINT g_strid_profiles[]= { IDS_PROFILES, 0};
  123. const UINT g_strid_users[]= { IDS_USERS, 0};
  124. */
  125. const UINT g_strid_subnets[]= { IDS_SUBNETCONFIGS, 0};
  126. //==========================================================
  127. // CACSUIInfo structures
  128. //
  129. // Root handle
  130. CACSUIInfo g_RootUIInfo =
  131. {
  132. g_strid_root, // static string
  133. 1, // only name column
  134. g_col_strid_name, //m_aColumnIds;
  135. g_col_width_name, //m_aColumnWidths;
  136. false, //m_bPropertyPage;
  137. true, //m_bContainer;
  138. NULL, //m_aNewMenuTextIds;
  139. NULL, //m_aNewMenuIds;
  140. NULL, //m_aTaskMenuTextIds;
  141. NULL, //m_aTaskMenuIds;
  142. g_verbs_all_hiden, //m_pVerbStates
  143. &CLSID_ACSRootNode
  144. };
  145. // Global Configuration handle
  146. CACSUIInfo g_GlobalUIInfo =
  147. {
  148. g_strid_global, // static string
  149. 1, // only name column
  150. g_col_strid_policy, //m_aColumnIds;
  151. g_col_width_policy, //m_aColumnWidths;
  152. false, //m_bPropertyPage;
  153. true, //m_bContainer;
  154. NULL, // g_new_menus_user, //m_aNewMenuTextIds;
  155. NULL, //m_aNewMenuIds;
  156. g_new_menus_policy, //m_aTaskMenuTextIds;
  157. NULL, //m_aTaskMenuIds;
  158. g_verbs_refresh, //m_pVerbStates
  159. &CLSID_ACSGlobalHolderNode
  160. };
  161. // Subnetworks Configuration handle
  162. CACSUIInfo g_SubnetworksUIInfo =
  163. {
  164. g_strid_subnets, // static string
  165. 1, // only name column
  166. g_col_strid_subnet, //m_aColumnIds;
  167. g_col_width_subnet, //m_aColumnWidths;
  168. false, //m_bPropertyPage;
  169. true, //m_bContainer;
  170. NULL, // g_new_menus_newsub, //m_aNewMenuTextIds;
  171. NULL, //m_aNewMenuIds;
  172. g_new_menus_newsub, //m_aTaskMenuTextIds;
  173. NULL, //m_aTaskMenuIds;
  174. g_verbs_refresh, //m_pVerbStates
  175. &CLSID_ACSSubnetHolderNode
  176. };
  177. // Policy handle
  178. CACSUIInfo g_PolicyUIInfo =
  179. {
  180. NULL, // static string id
  181. sizeof(g_col_strid_policy) / sizeof(UINT) -1, // the last string id is 0, so decrease by 1
  182. g_col_strid_policy, //m_aColumnIds;
  183. g_col_width_policy, //m_aColumnWidths;
  184. true, //m_bPropertyPage;
  185. false, //m_bContainer;
  186. NULL, //m_aNewMenuTextIds;
  187. NULL, //m_aNewMenuIds;
  188. NULL, //m_aTaskMenuTextIds;
  189. NULL, //m_aTaskMenuIds;
  190. g_verbs_property_delete, //m_pVerbStates
  191. &CLSID_ACSPolicyNode
  192. };
  193. // Subnet handle
  194. CACSUIInfo g_SubnetUIInfo =
  195. {
  196. NULL, // static string id
  197. sizeof(g_col_strid_subnet) / sizeof(UINT) -1, // decrease by 1, since the last IDS is 0
  198. g_col_strid_policy, //m_aColumnIds;
  199. g_col_width_policy, //m_aColumnWidths;
  200. true, //m_bPropertyPage;
  201. true, //m_bContainer;
  202. NULL, //g_new_menus_user, //m_aNewMenuTextIds;
  203. NULL, //m_aNewMenuIds;
  204. g_menus_subnet, //m_aTaskMenuTextIds;
  205. NULL, //m_aTaskMenuIds;
  206. g_verbs_property_refresh, //m_pVerbStates
  207. &CLSID_ACSSubnetNode
  208. };
  209. ///////////////////////////////////////////////////////////////////////////////
  210. //
  211. // CACSHandle implementation
  212. //
  213. ///////////////////////////////////////////////////////////////////////////////
  214. CACSHandle::CACSHandle(ITFSComponentData *pCompData, CDSObject* pDSObject, CACSUIInfo* pUIInfo)
  215. : CHandler(pCompData),
  216. m_pUIInfo(pUIInfo),
  217. m_dwShownState(0),
  218. m_pNode(NULL),
  219. m_pDSObject(pDSObject)
  220. {
  221. if(pDSObject)
  222. {
  223. pDSObject->AddRef();
  224. pDSObject->SetHandle(this);
  225. }
  226. ASSERT(pUIInfo);
  227. // init the static string array
  228. if(pUIInfo->m_aStaticStrIds)
  229. {
  230. const UINT* pUINT = pUIInfo->m_aStaticStrIds;
  231. int i = 0;
  232. while(*pUINT)
  233. {
  234. i++;
  235. m_aStaticStrings.AddByRID(*pUINT++);
  236. }
  237. m_nFirstDynCol = i;
  238. }
  239. else
  240. m_nFirstDynCol = 0;
  241. m_ulIconIndex = IMAGE_IDX_CLOSEDFOLDER;
  242. m_ulIconIndexOpen = IMAGE_IDX_OPENFOLDER;
  243. m_nBranchFlag = 0;
  244. m_bACSHandleExpanded = FALSE;
  245. m_bCheckPropertyPageOpen = TRUE;
  246. };
  247. CACSHandle::~CACSHandle()
  248. {
  249. m_aStaticStrings.DeleteAll();
  250. if(m_pDSObject)
  251. m_pDSObject->Release();
  252. };
  253. /*!--------------------------------------------------------------------------
  254. MachineHandler::DestroyHandler
  255. -
  256. Author: KennT
  257. ---------------------------------------------------------------------------*/
  258. STDMETHODIMP CACSHandle::DestroyResultHandler(LONG_PTR cookie)
  259. {
  260. SPITFSNode spNode;
  261. HRESULT hr = S_OK;
  262. if (S_OK != m_spNodeMgr->FindNode(cookie, &spNode))
  263. return S_FALSE;
  264. if (S_OK == BringUpPropertyPageIfOpen(spNode, NULL))
  265. {
  266. AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
  267. return S_FALSE;
  268. }
  269. else
  270. return S_OK;
  271. return hrOK;
  272. }
  273. /*!--------------------------------------------------------------------------
  274. MachineHandler::DestroyHandler
  275. -
  276. Author: KennT
  277. ---------------------------------------------------------------------------*/
  278. STDMETHODIMP CACSHandle::DestroyHandler(ITFSNode *pNode)
  279. {
  280. if (S_OK == BringUpPropertyPageIfOpen(pNode, NULL))
  281. {
  282. AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
  283. return S_FALSE;
  284. }
  285. else
  286. return S_OK;
  287. }
  288. //=============================================================================
  289. // CACSHandle::HasPropertyPages
  290. // Implementation of ITFSNodeHandler::HasPropertyPages
  291. // NOTE: the root node handler has to over-ride this function to
  292. // handle the snapin manager property page (wizard) case!!!
  293. //
  294. // Author: KennT, WeiJiang
  295. //=============================================================================
  296. STDMETHODIMP
  297. CACSHandle::HasPropertyPages
  298. (
  299. ITFSNode * pNode,
  300. LPDATAOBJECT pDataObject,
  301. DATA_OBJECT_TYPES type,
  302. DWORD dwType
  303. )
  304. {
  305. HRESULT hr = hrOK;
  306. if (dwType & TFS_COMPDATA_CREATE)
  307. {
  308. // This is the case where we are asked to bring up property
  309. // pages when the user is adding a new snapin. These calls
  310. // are forwarded to the root node to handle.
  311. hr = S_FALSE;
  312. }
  313. else
  314. {
  315. hr = (m_pUIInfo->m_bPropertyPage? S_OK : S_FALSE);
  316. }
  317. return hr;
  318. }
  319. /*!--------------------------------------------------------------------------
  320. CACSHandle::OnAddMenuItems
  321. Implementation of ITFSNodeHandler::OnAddMenuItems
  322. Author: KennT, WeiJiang
  323. ---------------------------------------------------------------------------*/
  324. STDMETHODIMP CACSHandle::OnAddMenuItems(
  325. ITFSNode *pNode,
  326. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  327. LPDATAOBJECT lpDataObject,
  328. DATA_OBJECT_TYPES type,
  329. DWORD dwType,
  330. long *pInsertionsAllowed)
  331. {
  332. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  333. HRESULT hr = S_OK;
  334. BOOL bExtension = !!(dwType & TFS_COMPDATA_EXTENSION);
  335. CString stMenuItem;
  336. if(*pInsertionsAllowed & CCM_INSERTIONALLOWED_NEW)
  337. // if (type == CCT_SCOPE)
  338. {
  339. int i = 0;
  340. long lInsertionId;
  341. long lMenuText;
  342. long lMenuId;
  343. // under new menu
  344. while(hr == S_OK && m_pUIInfo->m_aNewMenuTextIds && m_pUIInfo->m_aNewMenuTextIds[i])
  345. {
  346. // lInsertionId = bExtension ? CCM_INSERTIONPOINTID_3RDPARTY_NEW :
  347. // CCM_INSERTIONPOINTID_PRIMARY_NEW;
  348. // BUG :: bExtension is alway true for same reason
  349. lInsertionId = CCM_INSERTIONPOINTID_PRIMARY_NEW;
  350. lMenuText = m_pUIInfo->m_aNewMenuTextIds[i];
  351. if(m_pUIInfo->m_aNewMenuIds)
  352. lMenuId = m_pUIInfo->m_aNewMenuIds[i];
  353. else
  354. lMenuId = lMenuText;
  355. stMenuItem.LoadString(lMenuText);
  356. hr = LoadAndAddMenuItem( pContextMenuCallback,
  357. stMenuItem,
  358. lMenuId,
  359. lInsertionId,
  360. 0 );
  361. i++;
  362. }
  363. i = 0;
  364. // under task menu
  365. while(hr == S_OK && m_pUIInfo->m_aTaskMenuTextIds && m_pUIInfo->m_aTaskMenuTextIds[i])
  366. {
  367. lInsertionId = bExtension ? CCM_INSERTIONPOINTID_3RDPARTY_TASK :
  368. CCM_INSERTIONPOINTID_PRIMARY_TOP;
  369. // BUG :: bExtension is alway true for same reason
  370. lInsertionId = CCM_INSERTIONPOINTID_PRIMARY_TOP;
  371. lMenuText = m_pUIInfo->m_aTaskMenuTextIds[i];
  372. stMenuItem.LoadString(lMenuText);
  373. if(m_pUIInfo->m_aTaskMenuIds)
  374. lMenuText = m_pUIInfo->m_aTaskMenuTextIds[i];
  375. else
  376. lMenuId = lMenuText;
  377. hr = LoadAndAddMenuItem( pContextMenuCallback,
  378. stMenuItem,
  379. lMenuId,
  380. lInsertionId,
  381. 0 );
  382. i++;
  383. }
  384. }
  385. return hr;
  386. }
  387. STDMETHODIMP CACSHandle::AddMenuItems(ITFSComponent *pComponent,
  388. MMC_COOKIE cookie,
  389. LPDATAOBJECT pDataObject,
  390. LPCONTEXTMENUCALLBACK pCallback,
  391. long *pInsertionAllowed)
  392. {
  393. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  394. HRESULT hr = hrOK;
  395. SPITFSNode spNode;
  396. m_spNodeMgr->FindNode(cookie, &spNode);
  397. // Call through to the regular OnAddMenuItems
  398. if(*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW)
  399. hr = OnAddMenuItems(spNode,
  400. pCallback,
  401. pDataObject,
  402. CCT_RESULT,
  403. TFS_COMPDATA_CHILD_CONTEXTMENU,
  404. pInsertionAllowed);
  405. return hr;
  406. }
  407. /*!--------------------------------------------------------------------------
  408. PortsNodeHandler::Command
  409. -
  410. Author: KennT
  411. ---------------------------------------------------------------------------*/
  412. STDMETHODIMP CACSHandle::Command(ITFSComponent *pComponent,
  413. MMC_COOKIE cookie,
  414. int nCommandID,
  415. LPDATAOBJECT pDataObject)
  416. {
  417. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  418. HRESULT hr = hrOK;
  419. SPITFSNode spNode;
  420. m_spNodeMgr->FindNode(cookie, &spNode);
  421. // Call through to the regular OnCommand
  422. hr = OnCommand(spNode,
  423. nCommandID,
  424. CCT_RESULT,
  425. pDataObject,
  426. TFS_COMPDATA_CHILD_CONTEXTMENU);
  427. return hr;
  428. }
  429. /*!--------------------------------------------------------------------------
  430. CACSHandle::OnCommand
  431. Implementation of ITFSNodeHandler::OnCommand
  432. Author: KennT, WeiJiang
  433. ---------------------------------------------------------------------------*/
  434. STDMETHODIMP CACSHandle::OnCommand(ITFSNode *pNode, long nCommandId,
  435. DATA_OBJECT_TYPES type,
  436. LPDATAOBJECT pDataObject,
  437. DWORD dwType)
  438. {
  439. TRACE(_T("Command ID %d or %x is activated\n"), nCommandId, nCommandId);
  440. return S_OK;
  441. }
  442. /*!--------------------------------------------------------------------------
  443. CACSHandle::GetString
  444. Implementation of ITFSNodeHandler::GetString
  445. Author: KennT, WeiJiang
  446. ---------------------------------------------------------------------------*/
  447. STDMETHODIMP_(LPCTSTR) CACSHandle::GetString(ITFSNode *pNode, int nCol)
  448. {
  449. if(nCol < 0)
  450. // should be ROOT node
  451. nCol = 0;
  452. if(nCol < m_aStaticStrings.GetSize())
  453. return *m_aStaticStrings[(INT_PTR)nCol];
  454. else
  455. {
  456. ASSERT(nCol >= m_nFirstDynCol);
  457. UINT dynCol = nCol - m_nFirstDynCol;
  458. if(m_aDynStrings.GetSize() == 0) // new, not initialized yet
  459. UpdateStrings();
  460. if( nCol - m_nFirstDynCol < m_aDynStrings.GetSize())
  461. return *(m_aDynStrings.GetAt(dynCol));
  462. else
  463. return NULL;
  464. }
  465. }
  466. // should call the data object to get the latest dynamic strings
  467. HRESULT CACSHandle::UpdateStrings()
  468. {
  469. CString* pStr;
  470. UINT nCol;
  471. HRESULT hr = S_OK;
  472. UINT dynCol;
  473. for( nCol = m_nFirstDynCol, dynCol = 0; nCol < m_pUIInfo->m_nTotalStrs; nCol++, dynCol++)
  474. {
  475. if(nCol - m_nFirstDynCol < m_aDynStrings.GetSize())
  476. pStr = m_aDynStrings.GetAt(dynCol);
  477. else
  478. {
  479. pStr = new CString();
  480. m_aDynStrings.Add(pStr);
  481. }
  482. hr = m_pDSObject->GetString(*pStr, nCol);
  483. }
  484. return hr;
  485. }
  486. /*!--------------------------------------------------------------------------
  487. CDhcpScopeOptions::InitializeNode
  488. Initializes node specific data
  489. Author: EricDav
  490. ---------------------------------------------------------------------------*/
  491. HRESULT CACSHandle::InitializeNode
  492. (
  493. ITFSNode * pNode
  494. )
  495. {
  496. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  497. HRESULT hr = hrOK;
  498. ASSERT(m_pNode == NULL);
  499. m_pNode = pNode;
  500. if(m_pNode)
  501. m_pNode->AddRef();
  502. //
  503. // Create the display name for this scope
  504. //
  505. // Make the node immediately visible
  506. pNode->SetVisibilityState(TFS_VIS_SHOW);
  507. pNode->SetData(TFS_DATA_IMAGEINDEX, m_ulIconIndex);
  508. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, m_ulIconIndexOpen);
  509. pNode->SetData(TFS_DATA_COOKIE, (DWORD_PTR)(ITFSNode *) pNode);
  510. TRACE(_T("COOKIE -- %08x\n"), (DWORD_PTR)(ITFSNode *) pNode);
  511. pNode->SetData(TFS_DATA_USER, (DWORD_PTR) this);
  512. if(IfContainer())
  513. {
  514. SetColumnStringIDs(m_pUIInfo->m_aColumnIds);
  515. SetColumnWidths(m_pUIInfo->m_aColumnWidths);
  516. }
  517. return hr;
  518. }
  519. /*---------------------------------------------------------------------------
  520. CACSHandle::CompareItems
  521. Description
  522. ---------------------------------------------------------------------------*/
  523. STDMETHODIMP_(int)
  524. CACSHandle::CompareItems
  525. (
  526. ITFSComponent * pComponent,
  527. MMC_COOKIE cookieA,
  528. MMC_COOKIE cookieB,
  529. int nCol
  530. )
  531. {
  532. SPITFSNode spNode1, spNode2;
  533. m_spNodeMgr->FindNode(cookieA, &spNode1);
  534. m_spNodeMgr->FindNode(cookieB, &spNode2);
  535. CACSHandle *pSub1 = GETHANDLER(CACSHandle, spNode1);
  536. CACSHandle *pSub2 = GETHANDLER(CACSHandle, spNode2);
  537. LPCTSTR str1 = pSub1->GetString(NULL, nCol);
  538. LPCTSTR str2 = pSub2->GetString(NULL, nCol);
  539. if(str1 && str2)
  540. {
  541. CString str(str1);
  542. return str.Compare(str2);
  543. }
  544. else
  545. return 0;
  546. }
  547. /*!--------------------------------------------------------------------------
  548. CACSHandle::OnResultContextHelp
  549. Implementation of ITFSResultHandler::OnResultContextHelp
  550. Author: EricDav
  551. ---------------------------------------------------------------------------*/
  552. HRESULT
  553. CACSHandle::OnResultContextHelp
  554. (
  555. ITFSComponent * pComponent,
  556. LPDATAOBJECT pDataObject,
  557. MMC_COOKIE cookie,
  558. LPARAM arg,
  559. LPARAM lParam
  560. )
  561. {
  562. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  563. HRESULT hr = hrOK;
  564. SPIDisplayHelp spDisplayHelp;
  565. SPIConsole spConsole;
  566. pComponent->GetConsole(&spConsole);
  567. hr = spConsole->QueryInterface (IID_IDisplayHelp, (LPVOID*) &spDisplayHelp);
  568. ASSERT (SUCCEEDED (hr));
  569. if ( SUCCEEDED (hr) )
  570. {
  571. LPCTSTR pszHelpFile = m_spTFSCompData->GetHTMLHelpFileName();
  572. if (pszHelpFile == NULL)
  573. goto Error;
  574. CString szHelpFilePath;
  575. UINT nLen = ::GetWindowsDirectory (szHelpFilePath.GetBufferSetLength(2 * MAX_PATH), 2 * MAX_PATH);
  576. if (nLen == 0)
  577. {
  578. hr = E_FAIL;
  579. goto Error;
  580. }
  581. szHelpFilePath.ReleaseBuffer();
  582. szHelpFilePath += g_szDefaultHelpTopic;
  583. hr = spDisplayHelp->ShowTopic (T2OLE ((LPTSTR)(LPCTSTR) szHelpFilePath));
  584. ASSERT (SUCCEEDED (hr));
  585. }
  586. Error:
  587. return hr;
  588. }
  589. //=============================================================================
  590. // CACSHandle::OnResultSelect
  591. // -
  592. // Author: WeiJiang
  593. //
  594. HRESULT CACSHandle::OnResultSelect( ITFSComponent* pComponent,
  595. LPDATAOBJECT pDataObject,
  596. MMC_COOKIE cookie,
  597. LPARAM arg,
  598. LPARAM lParam)
  599. {
  600. HRESULT hr = hrOK;
  601. SPIConsoleVerb spConsoleVerb;
  602. int i;
  603. CORg (pComponent->GetConsoleVerb(&spConsoleVerb));
  604. // if it's ok to delete ... dynamic info
  605. // Set the states for verbs
  606. for(i = 0; i < ACS_TOTAL_MMC_VERBS; i++)
  607. {
  608. spConsoleVerb->SetVerbState(g_mmc_verbs[i], m_pUIInfo->m_pVerbStates[i], TRUE);
  609. }
  610. if (IsOkToDelete() == S_FALSE)
  611. spConsoleVerb->SetVerbState(MMC_VERB_DELETE, HIDDEN, TRUE);
  612. if (m_pUIInfo->m_pVerbStates[ ACS_MMC_VERB_PROPERTIES ] == ENABLED)
  613. spConsoleVerb->SetDefaultVerb(MMC_VERB_PROPERTIES);
  614. else
  615. spConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
  616. Error:
  617. return hr;
  618. }
  619. /*!--------------------------------------------------------------------------
  620. CACSHandle::GetString
  621. Implementation of ITFSResultHandler::GetString
  622. Author: KennT, WeiJiang
  623. ---------------------------------------------------------------------------*/
  624. STDMETHODIMP_(LPCTSTR)
  625. CACSHandle::GetString
  626. (
  627. ITFSComponent * pComponent,
  628. MMC_COOKIE cookie,
  629. int nCol
  630. )
  631. {
  632. return GetString(NULL, nCol);
  633. }
  634. /*!--------------------------------------------------------------------------
  635. CACSHandle::HasPropertyPages
  636. Implementation of ITFSResultHandler::HasPropertyPages
  637. Author: KennT, WeiJiang
  638. ---------------------------------------------------------------------------*/
  639. STDMETHODIMP
  640. CACSHandle::HasPropertyPages
  641. (
  642. ITFSComponent * pComponent,
  643. MMC_COOKIE cookie,
  644. LPDATAOBJECT pDataObject
  645. )
  646. {
  647. return (m_pUIInfo->m_bPropertyPage? S_OK : S_FALSE);
  648. }
  649. //=============================================================================
  650. // CACSHandle::AddChild
  651. // -
  652. // Author: WeiJiang
  653. //
  654. HRESULT CACSHandle::AddChild(
  655. ITFSNode* pNode,
  656. CACSHandle* pHandle,
  657. ITFSNode** ppNewNode)
  658. {
  659. HRESULT hr = S_OK;
  660. ASSERT(ppNewNode);
  661. ASSERT(pNode);
  662. ASSERT(pHandle);
  663. if(pHandle->IfContainer())
  664. {
  665. CHECK_HR(hr = CreateContainerTFSNode(ppNewNode,
  666. pHandle->m_pUIInfo->m_pGUID,
  667. pHandle,
  668. pHandle,
  669. m_spNodeMgr));
  670. }
  671. else
  672. {
  673. CHECK_HR(hr = CreateLeafTFSNode(ppNewNode,
  674. pHandle->m_pUIInfo->m_pGUID,
  675. pHandle,
  676. pHandle,
  677. m_spNodeMgr));
  678. }
  679. // Need to initialize the data for the root node
  680. CHECK_HR(hr = pHandle->InitializeNode(*ppNewNode));
  681. // Add the node to the root node
  682. CHECK_HR(hr = pNode->AddChild(*ppNewNode));
  683. L_ERR:
  684. return hr;
  685. }
  686. // when data is changed on property page
  687. HRESULT CACSHandle::NotifyDataChange(LPARAM param)
  688. {
  689. CACSHandle* pHandle = reinterpret_cast<CACSHandle*>(param);
  690. ASSERT(pHandle);
  691. ASSERT(pHandle->m_pNode);
  692. if(!pHandle->m_pNode)
  693. return S_FALSE; // not able to refresh the changes
  694. else
  695. {
  696. pHandle->m_pDSObject->SetNoObjectState();
  697. pHandle->UpdateStrings();
  698. if(pHandle->m_pNode->IsContainer())
  699. return pHandle->m_pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM);
  700. else
  701. return pHandle->m_pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM);
  702. }
  703. }
  704. /*---------------------------------------------------------------------------
  705. CACSHandle::OnCreateNodeId2
  706. Returns a unique string for this node
  707. Author: WeiJiang
  708. ---------------------------------------------------------------------------*/
  709. HRESULT CACSHandle::OnCreateNodeId2(ITFSNode * pNode, CString & strId,
  710. DWORD * dwFlags)
  711. {
  712. const GUID * pGuid = pNode->GetNodeType();
  713. CString strProviderId, strGuid;
  714. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  715. strGuid.ReleaseBuffer();
  716. // attach display name
  717. strId += GetString(NULL, 0);
  718. strId += strGuid;
  719. return hrOK;
  720. }
  721. //=============================================================================
  722. // CACSHandle::OnExpand
  723. // -
  724. // Author: WeiJiang
  725. //
  726. HRESULT CACSHandle::OnExpand(
  727. ITFSNode *pNode,LPDATAOBJECT pDataObjecct, DWORD dwType, LPARAM arg,LPARAM param)
  728. {
  729. HRESULT hr = hrOK;
  730. SPITFSNode spNode;
  731. std::list<CACSHandle*> children;
  732. std::list<CACSHandle*>::iterator i;
  733. if(arg)
  734. {
  735. hr = ListChildren(children);
  736. if (S_FALSE == hr)
  737. return S_OK;
  738. CHECK_HR(hr);
  739. // If this is TRUE, then we should enumerate the pane
  740. // add all children's handles
  741. for(i = children.begin(); i != children.end(); i++)
  742. {
  743. // For the root node, we will create one child node
  744. // Create a node
  745. spNode.Release(); // make sure the smart pointer is NULL
  746. CHECK_HR(hr = AddChild(pNode, (*i), &spNode));
  747. (*i)->Release(); // handle pointer,
  748. // Set the scope item for the root node
  749. // pNode->SetData(TFS_DATA_SCOPEID, param);
  750. // pNode->Show();
  751. }
  752. }
  753. m_bACSHandleExpanded = TRUE;
  754. L_ERR:
  755. pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA);
  756. if FAILED(hr)
  757. ReportError(hr, IDS_ERR_NODEEXPAND, NULL);
  758. return hr;
  759. }
  760. /*!--------------------------------------------------------------------------
  761. CACSHandle::SaveColumns
  762. -
  763. Author: EricDav
  764. ---------------------------------------------------------------------------*/
  765. HRESULT
  766. CACSHandle::SaveColumns
  767. (
  768. ITFSComponent * pComponent,
  769. MMC_COOKIE cookie,
  770. LPARAM arg,
  771. LPARAM lParam
  772. )
  773. {
  774. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  775. HRESULT hr = hrOK;
  776. DWORD dwNodeType;
  777. int nCol = 0;
  778. int nColWidth;
  779. SPITFSNode spNode, spRootNode;
  780. SPIHeaderCtrl spHeaderCtrl;
  781. BOOL bDirty = FALSE;
  782. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  783. CORg (pComponent->GetHeaderCtrl(&spHeaderCtrl));
  784. while (m_pUIInfo->m_aColumnIds[nCol] != 0)
  785. {
  786. hr = spHeaderCtrl->GetColumnWidth(nCol, &nColWidth);
  787. if (SUCCEEDED(hr) &&
  788. m_pUIInfo->m_aColumnWidths[nCol] != nColWidth)
  789. {
  790. m_pUIInfo->m_aColumnWidths[nCol] = nColWidth;
  791. bDirty = TRUE;
  792. }
  793. nCol++;
  794. }
  795. if (bDirty)
  796. {
  797. CORg (m_spNodeMgr->GetRootNode(&spRootNode));
  798. CORg(spRootNode->SetData(TFS_DATA_DIRTY, TRUE));
  799. }
  800. Error:
  801. return hr;
  802. }
  803. HRESULT CACSHandle::OnResultRefresh(ITFSComponent * pComponent,
  804. LPDATAOBJECT pDataObject,
  805. MMC_COOKIE cookie,
  806. LPARAM arg,
  807. LPARAM lParam)
  808. {
  809. HRESULT hr = hrOK;
  810. SPITFSNode spNode;
  811. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  812. CORg (spNode->DeleteAllChildren(true));
  813. CORg (OnExpand(spNode, pDataObject, 0, arg, lParam));
  814. Error:
  815. return hr;
  816. }
  817. HRESULT CACSHandle::OnDelete(ITFSNode *pNode, LPARAM arg, LPARAM lParam)
  818. {
  819. Trace0("CACSHandle::Notify(MMCN_DELETE) received\n");
  820. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  821. HRESULT hr = S_OK;
  822. CString strMessage, strTemp;
  823. try{
  824. strTemp.LoadString(IDS_DELETE_CONTAINER);
  825. strMessage.Format(strTemp, GetString(NULL, 0));
  826. }catch(CMemoryException&)
  827. {
  828. CHECK_HR(hr = E_OUTOFMEMORY);
  829. }
  830. if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
  831. {
  832. CHECK_HR(hr = Delete(pNode, NULL, TRUE));
  833. }
  834. L_ERR:
  835. if FAILED(hr)
  836. ReportError(hr, IDS_ERR_NODEDELETE, NULL);
  837. return hr;
  838. }
  839. HRESULT CACSHandle::OnRename(ITFSNode *pNode, LPARAM arg, LPARAM lParam)
  840. {
  841. Trace0("CACSHandle::Notify(MMCN_RENAME) received\n");
  842. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  843. HRESULT hr = S_OK;
  844. OLECHAR* pName = (OLECHAR*)lParam;
  845. hr = m_pDSObject->Rename(pName);
  846. if FAILED(hr)
  847. ReportError(hr, IDS_ERR_NODERENAME, NULL);
  848. return hr;
  849. }
  850. HRESULT CACSHandle::OnResultRename( ITFSComponent* pComponent,
  851. LPDATAOBJECT pDataObject,
  852. MMC_COOKIE cookie,
  853. LPARAM arg,
  854. LPARAM lParam)
  855. {
  856. Trace0("CACSHandle::Notify(MMCN_DELETE) received\n");
  857. OLECHAR* pName = (OLECHAR*)lParam;
  858. return m_pDSObject->Rename(pName);
  859. }
  860. HRESULT CACSHandle::OnResultDelete( ITFSComponent* pComponent,
  861. LPDATAOBJECT pDataObject,
  862. MMC_COOKIE cookie,
  863. LPARAM arg,
  864. LPARAM lParam)
  865. {
  866. Trace0("CACSHandle::Notify(MMCN_DELETE) received\n");
  867. HRESULT hr = S_OK;
  868. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  869. // build the list of selected nodes
  870. CTFSNodeList listNodesToDelete;
  871. hr = BuildSelectedItemList(pComponent, &listNodesToDelete);
  872. //
  873. // Confirm with the user
  874. //
  875. CString strMessage, strTemp;
  876. int nNodes = listNodesToDelete.GetCount();
  877. try{
  878. if (nNodes > 1)
  879. {
  880. strTemp.LoadString(IDS_DELETE_MULTIITEMS);
  881. strMessage.Format(strTemp, nNodes);
  882. }
  883. else
  884. {
  885. strTemp.LoadString(IDS_DELETE_ITEM);
  886. strMessage.Format(strTemp, GetString(NULL, 0));
  887. }
  888. }catch(CMemoryException&){
  889. CHECK_HR(hr = E_OUTOFMEMORY);
  890. }
  891. if (AfxMessageBox(strMessage, MB_YESNO) == IDNO)
  892. {
  893. return NOERROR;
  894. }
  895. //
  896. // Loop through all items deleting
  897. //
  898. while (listNodesToDelete.GetCount() > 0)
  899. {
  900. SPITFSNode spOptionNode;
  901. spOptionNode = listNodesToDelete.RemoveHead();
  902. CACSHandle* pOptItem = GETHANDLER(CACSHandle, spOptionNode);
  903. // call the other OnDelete Function to do the deletion
  904. CHECK_HR(hr = pOptItem->Delete(spOptionNode, pComponent, TRUE));
  905. if(hr != S_OK)
  906. goto L_ERR;
  907. spOptionNode.Release();
  908. }
  909. L_ERR:
  910. if FAILED(hr)
  911. ReportError(hr, IDS_ERR_NODEDELETE, NULL);
  912. return hr;
  913. }
  914. // bring up the property page if it's open
  915. HRESULT CACSHandle::BringUpPropertyPageIfOpen(ITFSNode *pNode, ITFSComponent* pTFSComponent)
  916. {
  917. HRESULT hr = S_OK;
  918. if(!m_bCheckPropertyPageOpen) return S_FALSE;
  919. CComPtr<IConsole2> spConsole;
  920. CComPtr<IDataObject> spDataObject;
  921. CComPtr<IComponentData> spComponentData;
  922. LONG_PTR uniqID;
  923. LONG_PTR cookie;
  924. hr = m_spNodeMgr->GetConsole(&spConsole);
  925. if (!spConsole)
  926. return S_FALSE;
  927. if ( hr != S_OK)
  928. return hr;
  929. // Query IConsole for the needed interface.
  930. CComQIPtr<IComponent, &IID_IComponent> spComponent(pTFSComponent);
  931. // Query IConsole for the needed interface.
  932. CComQIPtr<IPropertySheetProvider, &IID_IPropertySheetProvider> spPropertySheetProvider(spConsole );
  933. _ASSERTE( spPropertySheetProvider != NULL );
  934. cookie = pNode->GetData(TFS_DATA_COOKIE);
  935. // the find function FindPropertySheet takes cookie for result pane, and sopeId for scope pane
  936. if(pNode->IsContainer())
  937. uniqID = pNode->GetData(TFS_DATA_SCOPEID);
  938. else
  939. uniqID = cookie;
  940. CHECK_HR(hr = m_spNodeMgr->GetComponentData(&spComponentData));
  941. CHECK_HR(hr = spComponentData->QueryDataObject(cookie, pNode->IsContainer()?CCT_SCOPE:CCT_RESULT, &spDataObject));
  942. // This returns S_OK if a property sheet for this object already exists
  943. // and brings that property sheet to the foreground.
  944. // It returns S_FALSE if the property sheet wasn't found.
  945. // If this is coming in through my IComponent object, I pass the pComponent pointer.
  946. // If this is coming in through my IComponentData object,
  947. // then pComponent is NULL, which is the appropriate value to pass in for
  948. // the call to FindPropertySheet when coming in through IComponentData.
  949. hr = spPropertySheetProvider->FindPropertySheet(
  950. (LONG_PTR) uniqID
  951. , spComponent
  952. , spDataObject
  953. );
  954. L_ERR:
  955. return hr;
  956. }
  957. HRESULT CACSHandle::Delete(ITFSNode *pNode, ITFSComponent* pTFSComponent, BOOL bCheckPropertyPage)
  958. {
  959. Trace0("CACSHandle::Delete\n");
  960. HRESULT hr = S_OK;
  961. SPITFSNode spParent;
  962. if(bCheckPropertyPage) // check to see if the property page is open
  963. {
  964. if(BringUpPropertyPageIfOpen(pNode, pTFSComponent) == S_OK)
  965. {
  966. AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
  967. hr = S_FALSE;
  968. goto L_ERR;
  969. }
  970. }
  971. // delete the corresponding DS object
  972. CHECK_HR(hr = m_pDSObject->Delete());
  973. // remove from UI
  974. pNode->GetParent(&spParent);
  975. CHECK_HR(hr = spParent->RemoveChild(pNode));
  976. L_ERR:
  977. return hr;
  978. }
  979. unsigned int g_cfMachineName = RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  980. LPOLESTR g_RootTaskOverBitmaps[ROOT_TASK_MAX] =
  981. {
  982. L"/toolroll.bmp",
  983. };
  984. LPOLESTR g_RootTaskOffBitmaps[ROOT_TASK_MAX] =
  985. {
  986. L"/tool.bmp",
  987. };
  988. UINT g_RootTaskText[ROOT_TASK_MAX] =
  989. {
  990. IDS_ROOT_TASK_LAUNCH_ACS, // for the extension case
  991. };
  992. UINT g_RootTaskHelp[ROOT_TASK_MAX] =
  993. {
  994. IDS_ROOT_TASK_LAUNCH_ACS_HELP, // for the extension case
  995. };
  996. HRESULT
  997. CRootTasks::Init(BOOL bExtension, BOOL bThisMachine, BOOL bNetServices)
  998. {
  999. HRESULT hr = hrOK;
  1000. MMC_TASK mmcTask;
  1001. int nPos = 0;
  1002. int nFinish = ROOT_TASK_MAX - 2;
  1003. m_arrayMouseOverBitmaps.SetSize(ROOT_TASK_MAX);
  1004. m_arrayMouseOffBitmaps.SetSize(ROOT_TASK_MAX);
  1005. m_arrayTaskText.SetSize(ROOT_TASK_MAX);
  1006. m_arrayTaskHelp.SetSize(ROOT_TASK_MAX);
  1007. // setup path for reuse
  1008. OLECHAR szBuffer[MAX_PATH*2]; // that should be enough
  1009. lstrcpy (szBuffer, L"res://");
  1010. ::GetModuleFileName(_Module.GetModuleInstance(), szBuffer + lstrlen(szBuffer), MAX_PATH);
  1011. OLECHAR * temp = szBuffer + lstrlen(szBuffer);
  1012. if (bExtension && bThisMachine)
  1013. {
  1014. nPos = ROOT_TASK_MAX - 2;
  1015. nFinish = ROOT_TASK_MAX - 1;
  1016. }
  1017. else
  1018. if (bExtension && bNetServices)
  1019. {
  1020. nPos = ROOT_TASK_MAX - 1;
  1021. nFinish = ROOT_TASK_MAX;
  1022. }
  1023. else
  1024. {
  1025. nPos = ROOT_TASK_MAX;
  1026. nFinish = ROOT_TASK_MAX;
  1027. }
  1028. for (nPos; nPos < nFinish; nPos++)
  1029. {
  1030. m_arrayMouseOverBitmaps[nPos] = szBuffer;
  1031. m_arrayMouseOffBitmaps[nPos] = szBuffer;
  1032. m_arrayMouseOverBitmaps[nPos] += g_RootTaskOverBitmaps[nPos];
  1033. m_arrayMouseOffBitmaps[nPos] += g_RootTaskOffBitmaps[nPos];
  1034. m_arrayTaskText[nPos].LoadString(g_RootTaskText[nPos]);
  1035. m_arrayTaskHelp[nPos].LoadString(g_RootTaskHelp[nPos]);
  1036. AddTask((LPTSTR) (LPCTSTR) m_arrayMouseOverBitmaps[nPos],
  1037. (LPTSTR) (LPCTSTR) m_arrayMouseOffBitmaps[nPos],
  1038. (LPTSTR) (LPCTSTR) m_arrayTaskText[nPos],
  1039. (LPTSTR) (LPCTSTR) m_arrayTaskHelp[nPos],
  1040. MMC_ACTION_ID,
  1041. nPos);
  1042. }
  1043. return hr;
  1044. }
  1045. /*!--------------------------------------------------------------------------
  1046. CTapiRootHandler::TaskPadNotify
  1047. -
  1048. Author: EricDav
  1049. ---------------------------------------------------------------------------*/
  1050. STDMETHODIMP
  1051. CACSRootHandle::TaskPadNotify
  1052. (
  1053. ITFSComponent * pComponent,
  1054. MMC_COOKIE cookie,
  1055. LPDATAOBJECT pDataObject,
  1056. VARIANT * arg,
  1057. VARIANT * param
  1058. )
  1059. {
  1060. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1061. if (arg->vt == VT_I4)
  1062. {
  1063. switch (arg->lVal)
  1064. {
  1065. case ROOT_TASK_LAUNCH_ACS:
  1066. {
  1067. TCHAR SystemPath[MAX_PATH];
  1068. CString CommandLine;
  1069. GetSystemDirectory(SystemPath, MAX_PATH);
  1070. // to construct "mmc.exe /s %windir%\system32\acssnap.msc")
  1071. CommandLine = _T("mmc.exe /s ");
  1072. CommandLine += SystemPath;
  1073. CommandLine += _T("\\acssnap.msc");
  1074. USES_CONVERSION;
  1075. WinExec(T2A((LPTSTR)(LPCTSTR)CommandLine), SW_SHOW);
  1076. }
  1077. break;
  1078. default:
  1079. Panic1("CACSRootHandle::TaskPadNotify - Unrecognized command! %d", arg->lVal);
  1080. break;
  1081. }
  1082. }
  1083. return hrOK;
  1084. }
  1085. /*!--------------------------------------------------------------------------
  1086. CBaseResultHandler::EnumTasks
  1087. -
  1088. Author: EricDav
  1089. ---------------------------------------------------------------------------*/
  1090. STDMETHODIMP
  1091. CACSRootHandle::EnumTasks
  1092. (
  1093. ITFSComponent * pComponent,
  1094. MMC_COOKIE cookie,
  1095. LPDATAOBJECT pDataObject,
  1096. LPOLESTR pszTaskGroup,
  1097. IEnumTASK ** ppEnumTask
  1098. )
  1099. {
  1100. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1101. HRESULT hr = hrOK;
  1102. CRootTasks * pTasks = NULL;
  1103. SPIEnumTask spEnumTasks;
  1104. SPINTERNAL spInternal = ExtractInternalFormat(pDataObject);
  1105. BOOL bExtension = FALSE;
  1106. BOOL bAddThisMachineTasks = FALSE;
  1107. BOOL bAddNetServicesTasks = FALSE;
  1108. const CLSID * pNodeClsid = &CLSID_ACSSnap;
  1109. CString strMachineGroup = NETCONS_ROOT_THIS_MACHINE;
  1110. CString strNetServicesGroup = NETCONS_ROOT_NET_SERVICES;
  1111. if ((spInternal == NULL) || (*pNodeClsid != spInternal->m_clsid))
  1112. bExtension = TRUE;
  1113. if (bExtension &&
  1114. strMachineGroup.CompareNoCase(pszTaskGroup) == 0)
  1115. {
  1116. // There are multiple taskpad groups in the network console
  1117. // we need to make sure we are extending the correct one.
  1118. bAddThisMachineTasks = TRUE;
  1119. }
  1120. if (bExtension &&
  1121. strNetServicesGroup.CompareNoCase(pszTaskGroup) == 0)
  1122. {
  1123. // There are multiple taskpad groups in the network console
  1124. // we need to make sure we are extending the correct one.
  1125. bAddNetServicesTasks = TRUE;
  1126. }
  1127. COM_PROTECT_TRY
  1128. {
  1129. pTasks = new CRootTasks();
  1130. spEnumTasks = pTasks;
  1131. // if (!(bExtension && !bAddThisMachineTasks && !bAddNetServicesTasks))
  1132. CORg (pTasks->Init(bExtension, bAddThisMachineTasks, bAddNetServicesTasks));
  1133. CORg (pTasks->QueryInterface (IID_IEnumTASK, (void **)ppEnumTask));
  1134. COM_PROTECT_ERROR_LABEL;
  1135. }
  1136. COM_PROTECT_CATCH
  1137. return hr;
  1138. }
  1139. ///////////////////////////////////////////////////////////////////////////////
  1140. //
  1141. // CACSRootHandle
  1142. // -
  1143. // Author: WeiJiang
  1144. //
  1145. HRESULT CACSRootHandle::ListChildren(std::list<CACSHandle*>& children)
  1146. {
  1147. HRESULT hr = S_OK;
  1148. CACSHandle* pHandle = NULL;
  1149. CComObject<CACSGlobalObject>* pGlobal;
  1150. CComPtr<CACSGlobalObject> spGlobal;
  1151. CComObject<CACSSubnetsObject>* pSubnets;
  1152. CComPtr<CACSSubnetsObject> spSubnets;
  1153. // Global policy folder "cn=ACS,cn=Services,cn=Configuration"
  1154. CHECK_HR(hr = CComObject<CACSGlobalObject>::CreateInstance(&pGlobal)); // ref == 0
  1155. spGlobal = pGlobal;
  1156. // open the global folder
  1157. hr = pGlobal->Open();
  1158. // Change the title of the node to include the name of the domain
  1159. ASSERT(m_aStaticStrings[0]); // we assume root node has name
  1160. *m_aStaticStrings[(INT_PTR)0] += _T(" - ");
  1161. if(FAILED(hr) && pGlobal->m_nOpenErrorId)
  1162. {
  1163. ReportError(hr, IDS_ERR_ROOTNODE, NULL);
  1164. hr = S_OK;
  1165. goto L_ERR;
  1166. }
  1167. // if opened successfully, the get name of domain information
  1168. CHECK_HR(hr);
  1169. // Change the title of the node to include the name of the domain
  1170. ASSERT(m_aStaticStrings[0]); // we assume root node has name
  1171. *m_aStaticStrings[(INT_PTR)0] += pGlobal->m_strDomainName;
  1172. //================================
  1173. // global handle reuse the ACSROOTDS OBject
  1174. pHandle = new CACSGlobalHandle(m_spTFSCompData, pGlobal); // ref == 1
  1175. if(!pHandle)
  1176. CHECK_HR(hr = E_OUTOFMEMORY);
  1177. children.push_back(pHandle);
  1178. //=======================================
  1179. //Subnetworks configuration folder "cn=subnets,cn=sits,cn=configuration"
  1180. CHECK_HR(hr = CComObject<CACSSubnetsObject>::CreateInstance(&pSubnets)); // ref == 0
  1181. spSubnets = pSubnets;
  1182. if FAILED(hr = spSubnets->Open())
  1183. {
  1184. CHECK_HR(hr);
  1185. }
  1186. pHandle = new CACSSubnetContainerHandle(m_spTFSCompData, pSubnets); // ref == 1
  1187. if(!pHandle)
  1188. CHECK_HR(hr = E_OUTOFMEMORY);
  1189. children.push_back(pHandle);
  1190. L_ERR:
  1191. return hr;
  1192. }
  1193. ///////////////////////////////////////////////////////////////////////////////
  1194. //
  1195. // CACSSubnetContainerHandle
  1196. // -
  1197. // Author: WeiJiang
  1198. //
  1199. STDMETHODIMP CACSSubnetContainerHandle::OnCommand( ITFSNode* pNode,
  1200. long nCommandId,
  1201. DATA_OBJECT_TYPES type,
  1202. LPDATAOBJECT pDataObject,
  1203. DWORD dwType)
  1204. {
  1205. CStrArray Names;
  1206. HRESULT hr = S_OK;
  1207. CComObject<CDSObject>* pNTSubnetObj = NULL;
  1208. CComPtr<CDSObject> spNTSubnetObj;
  1209. CComObject<CACSSubnetObject>* pACSSubnetObj = NULL;
  1210. CComPtr<CACSSubnetObject> spACSSubnetObj;
  1211. CACSSubnetHandle* pHandle = NULL;
  1212. ITFSNode* pNewNode = NULL;
  1213. SPIComponentData spComponentData;
  1214. int i;
  1215. TRACE(_T("Command ID %d or %x is activated\n"), nCommandId, nCommandId);
  1216. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1217. switch(nCommandId)
  1218. {
  1219. case IDS_NEWSUBNET:
  1220. // get the object name -- which will be a new name within the container
  1221. CHECK_HR(hr = GetNamesForCommandNew(nCommandId, Names));
  1222. try{
  1223. // for each name, create an object in list
  1224. for(i = 0; i < Names.GetSize(); i++)
  1225. {
  1226. // create the object in DS
  1227. // need to create a subnet (NT subnet object in DS)
  1228. CHECK_HR(hr = CComObject<CDSObject>::CreateInstance(&pNTSubnetObj)); // ref == 0
  1229. spNTSubnetObj = pNTSubnetObj; // ref == 1, previous one get dereferenced
  1230. CHECK_HR(hr = spNTSubnetObj->Open( m_pDSObject,
  1231. L"subnet",
  1232. T2W((LPTSTR)(LPCTSTR)(*Names[(INT_PTR)i])),
  1233. true,
  1234. true));
  1235. m_pDSObject->AddChild(pNTSubnetObj);
  1236. // create ACS subobject within the subnet object ...
  1237. CHECK_HR(hr = CComObject<CACSSubnetObject>::CreateInstance(&pACSSubnetObj));
  1238. spACSSubnetObj = pACSSubnetObj;
  1239. CHECK_HR(hr = spACSSubnetObj->SetInfo(spNTSubnetObj, ACS_CLS_CONTAINER, ACS_NAME_ACS));
  1240. // create a handle and add to the node tree
  1241. pHandle = new CACSSubnetHandle(m_spTFSCompData, spACSSubnetObj);
  1242. // add this to snapin UI
  1243. if(!pHandle)
  1244. CHECK_HR(hr = E_OUTOFMEMORY);
  1245. AddChild(pNode, pHandle, &pNewNode);
  1246. // pNode->Show();
  1247. pNewNode->Show();
  1248. }
  1249. }catch(CMemoryException&){
  1250. CHECK_HR(hr = E_OUTOFMEMORY);
  1251. }
  1252. if(Names.GetSize() == 1)
  1253. {
  1254. // display the property page
  1255. m_spNodeMgr->GetComponentData(&spComponentData);
  1256. CHECK_HR( hr = DoPropertiesOurselvesSinceMMCSucks(pNewNode, (IComponentData*)spComponentData, *Names[(INT_PTR)0]));
  1257. }
  1258. break;
  1259. default:
  1260. CACSHandle::OnCommand(pNode, nCommandId, type, pDataObject, dwType);
  1261. }
  1262. L_ERR:
  1263. if(pHandle) pHandle->Release();
  1264. if FAILED(hr)
  1265. ReportError(hr, IDS_ERR_COMMAND, NULL);
  1266. return hr;
  1267. }
  1268. // container handler only list the subnets defined in NT, the ACS information is stored in
  1269. // 123.123.123.0/24 --> ACS --> Config
  1270. // the ACS becomes the real ACS subnet object
  1271. HRESULT CACSSubnetContainerHandle::ListChildren(std::list<CACSHandle*>& children)
  1272. {
  1273. HRESULT hr = S_OK;
  1274. CACSHandle* pHandle = NULL;
  1275. CComPtr<CDSObject> spNTSubnetObj;
  1276. CComPtr<CACSSubnetObject> spACSSubnetObj;
  1277. CComObject<CACSSubnetObject>* pACSSubnetObj = NULL;
  1278. CACSContainerObject<CDSObject>* pSubnetCont = NULL;
  1279. std::list<CDSObject*> ObjList;
  1280. std::list<CDSObject*>::iterator i;
  1281. pSubnetCont = dynamic_cast<CACSContainerObject<CDSObject>*>(m_pDSObject);
  1282. CHECK_HR(hr = pSubnetCont->ListChildren(ObjList, L"subnet"));
  1283. for( i = ObjList.begin(); i != ObjList.end(); i++)
  1284. {
  1285. spNTSubnetObj = *i; // this make a release call to the interface previously stored
  1286. CHECK_HR(hr = CComObject<CACSSubnetObject>::CreateInstance(&pACSSubnetObj));
  1287. spACSSubnetObj = pACSSubnetObj;
  1288. CHECK_HR(hr = spACSSubnetObj->SetInfo(spNTSubnetObj, ACS_CLS_CONTAINER, ACS_NAME_ACS));
  1289. spACSSubnetObj->SetNoObjectState();
  1290. pHandle = new CACSSubnetHandle(m_spTFSCompData, spACSSubnetObj); // ref == 1
  1291. if(!pHandle)
  1292. CHECK_HR(hr = E_OUTOFMEMORY);
  1293. children.push_back(pHandle);
  1294. }
  1295. L_ERR:
  1296. for( i = ObjList.begin(); i != ObjList.end(); i++)
  1297. {
  1298. (*i)->Release(); // release the data objects
  1299. }
  1300. return hr;
  1301. }
  1302. ///////////////////////////////////////////////////////////////////////////////
  1303. //
  1304. // CACSSubnetContainerHandle
  1305. // -
  1306. // Author: WeiJiang
  1307. //
  1308. HRESULT
  1309. CACSSubnetContainerHandle::GetNamesForCommandNew(int nCommandId, CStrArray& Names)
  1310. {
  1311. CDlgNewSubnet dlg;
  1312. CString* pStr = NULL;
  1313. dlg.SetNameList(m_pDSObject->GetChildrenNameList());
  1314. if(dlg.DoModal() == IDOK && dlg.m_strSubnetName.GetLength())
  1315. {
  1316. pStr = new CString(dlg.m_strSubnetName);
  1317. Names.Add(pStr);
  1318. return S_OK;
  1319. }
  1320. else
  1321. return S_FALSE;
  1322. }
  1323. ///////////////////////////////////////////////////////////////////////////////
  1324. //
  1325. // CACSPolicyContainerHandle
  1326. // -
  1327. // Author: WeiJiang
  1328. //
  1329. STDMETHODIMP
  1330. CACSSubnetHandle::OnCommand( ITFSNode* pNode,
  1331. long nCommandId,
  1332. DATA_OBJECT_TYPES type,
  1333. LPDATAOBJECT pDataObject,
  1334. DWORD dwType)
  1335. {
  1336. HRESULT hr = S_OK;
  1337. CACSSubnetObject* pACSSubnetObj = (CACSSubnetObject *)m_pDSObject;
  1338. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1339. switch(nCommandId)
  1340. {
  1341. case IDS_DELETESUBNET:
  1342. if(S_OK == BringUpPropertyPageIfOpen(pNode, NULL))
  1343. {
  1344. AfxMessageBox(IDS_ERROR_CLOSE_PROPERTY_SHEET);
  1345. hr = S_FALSE;
  1346. break;
  1347. }
  1348. if (AfxMessageBox(IDS_CONFIRM_DELETE, MB_YESNO) != IDYES)
  1349. break;
  1350. // delete the corresponding DS object -- subnet object is a special version, which keeps the C++ object, but delete the DS object underneath
  1351. hr = m_pDSObject->Delete();
  1352. if(hr == ERROR_NO_SUCH_OBJECT) // no such object
  1353. hr = S_FALSE;
  1354. CHECK_HR(hr);
  1355. // remove from UI -- to get rid of the sub object within it
  1356. if(hr == S_OK)
  1357. {
  1358. CHECK_HR(hr = pNode->DeleteAllChildren(true));
  1359. UpdateStrings();
  1360. }
  1361. break;
  1362. default:
  1363. hr = CACSPolicyContainerHandle::OnCommand(pNode, nCommandId, type, pDataObject, dwType);
  1364. break;
  1365. }
  1366. L_ERR:
  1367. if FAILED(hr)
  1368. ReportError(hr, IDS_ERR_COMMAND, NULL);
  1369. pACSSubnetObj->SetNoObjectState();
  1370. return hr;
  1371. }
  1372. // only shown conflict state here
  1373. HRESULT
  1374. CACSSubnetHandle::ShowState(DWORD state)
  1375. {
  1376. DWORD dwShownState = GetShownState();
  1377. HRESULT hr;
  1378. UINT id;
  1379. CHECK_HR(hr = CACSHandle::ShowState(state));
  1380. if(m_pNode == NULL)
  1381. return S_OK;
  1382. // change state on UI
  1383. id = ((state & ACSDATA_STATE_NOOBJECT) != 0)? IMAGE_IDX_SUBNETWORK_NO_ACSPOLICY : IMAGE_IDX_SUBNETWORK;
  1384. m_pNode->SetData(TFS_DATA_IMAGEINDEX, id);
  1385. m_pNode->SetData(TFS_DATA_OPENIMAGEINDEX, id);
  1386. hr = m_pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM);
  1387. //
  1388. L_ERR:
  1389. return hr;
  1390. }
  1391. ///////////////////////////////////////////////////////////////////////////////
  1392. //
  1393. // CACSHandle
  1394. // -
  1395. // Author: WeiJiang
  1396. //
  1397. STDMETHODIMP
  1398. CACSSubnetHandle::CreatePropertyPages
  1399. (
  1400. ITFSNode *pNode,
  1401. LPPROPERTYSHEETCALLBACK lpProvider,
  1402. LPDATAOBJECT pDataObject,
  1403. LONG_PTR handle,
  1404. DWORD dwType
  1405. )
  1406. {
  1407. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1408. HRESULT hr = S_OK;
  1409. DWORD dwError;
  1410. CString strServiceName;
  1411. CPgGeneral* pPgGeneral = NULL;
  1412. CPgServers* pPgServers = NULL;
  1413. CPgLogging* pPgLogging = NULL;
  1414. CPgAccounting* pPgAccounting = NULL;
  1415. CPgSBM* pPgSBM = NULL;
  1416. HPROPSHEETPAGE hPgGeneral = NULL;
  1417. HPROPSHEETPAGE hPgServers = NULL;
  1418. HPROPSHEETPAGE hPgLogging = NULL;
  1419. HPROPSHEETPAGE hPgAccounting = NULL;
  1420. HPROPSHEETPAGE hPgSBM = NULL;
  1421. BOOL bNewCreated = FALSE;
  1422. CComObject<CACSSubnetPageManager>* pPageManager;
  1423. hr = CComObject<CACSSubnetPageManager>::CreateInstance(&pPageManager);
  1424. if (FAILED(hr))
  1425. return hr;
  1426. CACSSubnetObject* pObj = dynamic_cast<CACSSubnetObject*>(m_pDSObject);
  1427. ASSERT(pObj); // expect this object to be this type
  1428. CComPtr<CACSSubnetConfig> spConfig;
  1429. CHECK_HR(hr = pObj->MakeSureExist(&bNewCreated)); // make sure the current DS object is active
  1430. m_pDSObject->SetNoObjectState();
  1431. // if this is new added policy, need to re-expand to make sure the new added ones can be seen
  1432. if(bNewCreated && m_bACSHandleExpanded)
  1433. {
  1434. // node already in Expanded state, need to manually expand again, since
  1435. CHECK_HR(hr = pNode->DeleteAllChildren(true));
  1436. // we re-created the data object
  1437. CHECK_HR(hr = OnExpand(pNode, pDataObject, 0, 1, 0));
  1438. }
  1439. pObj->GetConfig(&spConfig);
  1440. pPageManager->SetMMCNotify(handle, (LPARAM)this);
  1441. pPageManager->SetSubnetData(spConfig, this);
  1442. CHECK_HR(hr = spConfig->Reopen()); // make sure the current DS object is active
  1443. //===============
  1444. // general page -- traffic
  1445. {
  1446. CComPtr<CACSSubnetLimitsContainer> spLimitsCont;
  1447. pObj->GetLimitsContainer(&spLimitsCont);
  1448. CHECK_HR(hr = spLimitsCont->Reopen()); // make sure the current DS object is active
  1449. pPgGeneral = new CPgGeneral((CACSSubnetConfig*)spConfig, (CACSContainerObject<CACSSubnetServiceLimits>*) spLimitsCont );
  1450. pPageManager->AddPage(pPgGeneral);
  1451. }
  1452. // tell MMC to hook the proc because we are running on a separate,
  1453. // non MFC thread.
  1454. // change callback function to delete itself when the property sheet is released
  1455. pPgGeneral->SetSelfDeleteCallback();
  1456. MMCPropPageCallback(&pPgGeneral->m_psp);
  1457. hPgGeneral = ::CreatePropertySheetPage(&pPgGeneral->m_psp);
  1458. if(hPgGeneral == NULL)
  1459. return E_UNEXPECTED;
  1460. lpProvider->AddPage(hPgGeneral);
  1461. //===============
  1462. // Servers page
  1463. pPgServers = new CPgServers((CACSSubnetConfig*)spConfig);
  1464. pPageManager->AddPage(pPgServers);
  1465. // tell MMC to hook the proc because we are running on a separate,
  1466. // non MFC thread.
  1467. // change callback function to delete itself when the property sheet is released
  1468. pPgServers->SetSelfDeleteCallback();
  1469. MMCPropPageCallback(&pPgServers->m_psp);
  1470. hPgServers = ::CreatePropertySheetPage(&pPgServers->m_psp);
  1471. if(hPgServers == NULL)
  1472. return E_UNEXPECTED;
  1473. lpProvider->AddPage(hPgServers);
  1474. //===============
  1475. // logging page
  1476. pPgLogging = new CPgLogging((CACSSubnetConfig*)spConfig);
  1477. pPageManager->AddPage(pPgLogging);
  1478. // tell MMC to hook the proc because we are running on a separate,
  1479. // non MFC thread.
  1480. pPgLogging->SetSelfDeleteCallback();
  1481. MMCPropPageCallback(&pPgLogging->m_psp);
  1482. hPgLogging = ::CreatePropertySheetPage(&pPgLogging->m_psp);
  1483. if(hPgLogging == NULL)
  1484. return E_UNEXPECTED;
  1485. lpProvider->AddPage(hPgLogging);
  1486. //===============
  1487. // Accouting page -- added by WeiJiang 2/16/98
  1488. pPgAccounting = new CPgAccounting((CACSSubnetConfig*)spConfig);
  1489. pPageManager->AddPage(pPgAccounting);
  1490. // tell MMC to hook the proc because we are running on a separate,
  1491. // non MFC thread.
  1492. pPgAccounting->SetSelfDeleteCallback();
  1493. MMCPropPageCallback(&pPgAccounting->m_psp);
  1494. hPgAccounting = ::CreatePropertySheetPage(&pPgAccounting->m_psp);
  1495. if(hPgAccounting == NULL)
  1496. return E_UNEXPECTED;
  1497. lpProvider->AddPage(hPgAccounting);
  1498. //===============
  1499. // advanced page -- SBM
  1500. pPgSBM = new CPgSBM((CACSSubnetConfig*)spConfig);
  1501. pPageManager->AddPage(pPgSBM);
  1502. // tell MMC to hook the proc because we are running on a separate,
  1503. // non MFC thread.
  1504. pPgSBM->SetSelfDeleteCallback();
  1505. MMCPropPageCallback(&pPgSBM->m_psp);
  1506. hPgSBM = ::CreatePropertySheetPage(&pPgSBM->m_psp);
  1507. if(hPgSBM == NULL)
  1508. return E_UNEXPECTED;
  1509. lpProvider->AddPage(hPgSBM);
  1510. L_ERR: //
  1511. if FAILED(hr)
  1512. ReportError(hr, IDS_ERR_PROPERTYPAGE, NULL);
  1513. return hr;
  1514. }
  1515. ///////////////////////////////////////////////////////////////////////////////
  1516. //
  1517. // CACSPolicyContainerHandle
  1518. // -
  1519. // Author: WeiJiang
  1520. //
  1521. STDMETHODIMP
  1522. CACSPolicyContainerHandle::OnCommand( ITFSNode* pNode,
  1523. long nCommandId,
  1524. DATA_OBJECT_TYPES type,
  1525. LPDATAOBJECT pDataObject,
  1526. DWORD dwType)
  1527. {
  1528. CStrArray Names;
  1529. HRESULT hr = S_OK;
  1530. CComObject<CACSPolicyElement>* pDSObj = NULL;
  1531. CComPtr<CACSPolicyElement> spObj;
  1532. CACSPolicyHandle* pHandle = NULL;
  1533. ITFSNode* pNewNode = NULL;
  1534. SPIComponentData spComponentData;
  1535. CACSSubnetObject* pSubnetObj;
  1536. int i, j;
  1537. TCHAR szNameCanonical[MAX_PATH * 2];
  1538. ULONG len = MAX_PATH * 2;
  1539. TRACE(_T("Command ID %d or %x is activated\n"), nCommandId, nCommandId);
  1540. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1541. switch(nCommandId)
  1542. {
  1543. case IDS_NEWPOLICY:
  1544. // get the object name -- which will be a new name within the container
  1545. CHECK_HR(hr = GetNamesForCommandNew(nCommandId, Names));
  1546. // for each name, create an object in list
  1547. try{
  1548. for(i = 0; i < Names.GetSize(); i++)
  1549. {
  1550. // create the object in DS
  1551. CHECK_HR(hr = CComObject<CACSPolicyElement>::CreateInstance(&pDSObj)); // ref == 0
  1552. spObj = pDSObj; // ref == 1
  1553. CString* pStr;
  1554. try{
  1555. pSubnetObj = dynamic_cast<CACSSubnetObject*>(m_pDSObject);
  1556. }
  1557. catch(...)
  1558. {
  1559. };
  1560. if(pSubnetObj) // the policy is in subnet folder, otherwise, it will be global
  1561. {
  1562. BOOL bNew;
  1563. CHECK_HR(hr = pSubnetObj->MakeSureExist(&bNew));
  1564. if(bNew)
  1565. {
  1566. CHECK_HR(hr = pNode->DeleteAllChildren(true));
  1567. CHECK_HR(hr = OnExpand(pNode, pDataObject, 0, 1, 0));
  1568. }
  1569. }
  1570. spObj->SetFlags(ATTR_FLAG_SAVE, spObj->SetDefault(), true);
  1571. CHECK_HR(hr = spObj->Open( m_pDSObject,
  1572. ACS_CLS_POLICY,
  1573. T2W((LPTSTR)(LPCTSTR)*Names[(INT_PTR)i]),
  1574. true,
  1575. true));
  1576. spObj->m_bUseName_NewPolicy = TRUE;
  1577. m_pDSObject->AddChild(pDSObj);
  1578. // create a handle and add to the node tree
  1579. pHandle = new CACSPolicyHandle(m_spTFSCompData, spObj);
  1580. CHECK_HR(hr = spObj->Close());
  1581. // add this to snapin UI
  1582. AddChild(pNode, pHandle, &pNewNode);
  1583. if(!pHandle)
  1584. CHECK_HR(hr = E_OUTOFMEMORY);
  1585. pNode->Show();
  1586. }
  1587. // Display the property pages if there is only one new policy added
  1588. if(Names.GetSize() == 1)
  1589. {
  1590. CString newPolicyName;
  1591. newPolicyName.LoadString(IDS_NEWACSPOLICY);
  1592. // display the property page
  1593. m_spNodeMgr->GetComponentData(&spComponentData);
  1594. pHandle->SetDeleteOnCancelPropertyPage(pNewNode);
  1595. CHECK_HR( hr = DoPropertiesOurselvesSinceMMCSucks(pNewNode, (IComponentData*)spComponentData, newPolicyName));
  1596. }
  1597. }catch(CMemoryException&){
  1598. CHECK_HR(hr = E_OUTOFMEMORY);
  1599. }
  1600. break;
  1601. default:
  1602. CACSHandle::OnCommand(pNode, nCommandId, type, pDataObject, dwType);
  1603. break;
  1604. }
  1605. L_ERR:
  1606. if(pHandle) pHandle->Release();
  1607. if FAILED(hr)
  1608. ReportError(hr, IDS_ERR_COMMAND, NULL);
  1609. return hr;
  1610. }
  1611. HRESULT CACSPolicyContainerHandle::OnExpand(
  1612. ITFSNode *pNode,LPDATAOBJECT pDataObject, DWORD dwType, LPARAM arg,LPARAM param)
  1613. {
  1614. HRESULT hr = hrOK;
  1615. CACSPolicyContainer* pCont = NULL;
  1616. CHECK_HR(hr = CACSHandle::OnExpand(pNode, pDataObject, dwType, arg, param));
  1617. pCont = dynamic_cast<CACSPolicyContainer*>(m_pDSObject);
  1618. pCont->SetChildrenConflictState();
  1619. L_ERR:
  1620. return hr;
  1621. }
  1622. HRESULT CACSPolicyContainerHandle::ListChildren(std::list<CACSHandle*>& children)
  1623. {
  1624. HRESULT hr = S_OK;
  1625. CACSHandle* pHandle = NULL;
  1626. CComPtr<CDSObject> spObj;
  1627. CACSPolicyContainer* pCont = NULL;
  1628. std::list<CACSPolicyElement*> ObjList;
  1629. std::list<CACSPolicyElement*>::iterator i;
  1630. pCont = dynamic_cast<CACSPolicyContainer*>(m_pDSObject);
  1631. hr = pCont->ListChildren(ObjList, ACS_CLS_POLICY);
  1632. if(hr == ERROR_NO_SUCH_OBJECT) // object is not found in DS, it's fine, since, some subnet with no ACS info
  1633. {
  1634. hr = S_OK;
  1635. goto L_ERR;
  1636. }
  1637. CHECK_HR(hr);
  1638. for( i = ObjList.begin(); i != ObjList.end(); i++)
  1639. {
  1640. spObj = *i; // this make a release call to the interface previously stored
  1641. pHandle = new CACSPolicyHandle(m_spTFSCompData, spObj);
  1642. CACSPolicyElement* pPolicy = dynamic_cast<CACSPolicyElement*>((CDSObject*)spObj);
  1643. ASSERT(pPolicy);
  1644. if(!pHandle)
  1645. CHECK_HR(hr = E_OUTOFMEMORY);
  1646. pHandle->SetBranch(m_nBranchFlag);
  1647. children.push_back(pHandle);
  1648. }
  1649. L_ERR:
  1650. for( i = ObjList.begin(); i != ObjList.end(); i++)
  1651. {
  1652. (*i)->Release();
  1653. }
  1654. return hr;
  1655. }
  1656. ///////////////////////////////////////////////////////////////////////////////
  1657. //
  1658. // CACSPolicyContainerHandle
  1659. // -
  1660. // Author: WeiJiang
  1661. //
  1662. HRESULT
  1663. CACSPolicyContainerHandle::GetNamesForCommandNew(int nCommandId, CStrArray& Names)
  1664. {
  1665. // name of a policy is not important to the consumer of the policy
  1666. // policy name is constructed as AcsPolicyYYYYMMDDMMn, AcsPolicy198808211236
  1667. ASSERT(nCommandId == IDS_NEWPOLICY);
  1668. CString* pstrName = new CString();
  1669. SYSTEMTIME sysTime;
  1670. GetSystemTime(&sysTime);
  1671. pstrName->Format(_T("AcsPolicy%04d%02d%02d%02d%02d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute);
  1672. CStrArray* pExistingNames = m_pDSObject->GetChildrenNameList();
  1673. int i = 0;
  1674. while(pExistingNames && pExistingNames->Find(*pstrName) != -1) // found in existing names
  1675. {
  1676. // try next name with
  1677. pstrName->Format(_T("AcsPolicy%04d%02d%02d%02d%02d%-d"), sysTime.wYear, sysTime.wMonth, sysTime.wDay, sysTime.wHour, sysTime.wMinute, i++);
  1678. };
  1679. Names.Add(pstrName);
  1680. if (!Names.GetSize())
  1681. return S_OK;
  1682. else
  1683. return S_FALSE;
  1684. }
  1685. ///////////////////////////////////////////////////////////////////////////////
  1686. //
  1687. // CACSPolicyHandle
  1688. // -
  1689. // Author: WeiJiang
  1690. //
  1691. /*!--------------------------------------------------------------------------
  1692. CACSPolicyHandle::CreatePropertyPages
  1693. Implementation of ITFSResultHandler::CreatePropertyPages
  1694. Author: KennT
  1695. ---------------------------------------------------------------------------*/
  1696. STDMETHODIMP
  1697. CACSPolicyHandle::CreatePropertyPages
  1698. (
  1699. ITFSNode *pNode,
  1700. LPPROPERTYSHEETCALLBACK lpProvider,
  1701. LPDATAOBJECT pDataObject,
  1702. LONG_PTR handle,
  1703. DWORD dwType
  1704. )
  1705. {
  1706. return CreatePropertyPages((ITFSComponent*)NULL, (long) 0, lpProvider, pDataObject, handle);
  1707. }
  1708. HRESULT CACSPolicyHandle::OnResultDelete( ITFSComponent* pComponent,
  1709. LPDATAOBJECT pDataObject,
  1710. MMC_COOKIE cookie,
  1711. LPARAM arg,
  1712. LPARAM lParam)
  1713. {
  1714. Trace0("CACSPolicyHandle::Notify(MMCN_DELETE) received\n");
  1715. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1716. CComPtr<CACSPolicyContainer> spCont;
  1717. // GetContainer already AddRef, so avoid AddRef twice, assign directly to .p
  1718. spCont.p = dynamic_cast<CACSPolicyContainer*>(m_pDSObject->GetContainer());
  1719. HRESULT hr = CACSHandle::OnResultDelete(pComponent, pDataObject, cookie, arg, lParam);
  1720. spCont->SetChildrenConflictState();
  1721. return hr;
  1722. }
  1723. // only shown conflict state here
  1724. HRESULT
  1725. CACSPolicyHandle::ShowState(DWORD state)
  1726. {
  1727. DWORD dwShownState = GetShownState();
  1728. HRESULT hr;
  1729. UINT id;
  1730. CHECK_HR(hr = CACSHandle::ShowState(state));
  1731. if(m_pNode == NULL)
  1732. return S_OK;
  1733. /*
  1734. ||
  1735. (dwShownState & (ACSDATA_STATE_CONFLICT | ACSDATA_STATE_DISABLED)) == (state & (ACSDATA_STATE_CONFLICT | ACSDATA_STATE_DISABLED)))
  1736. return S_OK;
  1737. */
  1738. // change conflict state on UI
  1739. id = ((state & ACSDATA_STATE_CONFLICT) != 0)? IMAGE_IDX_CONFLICTPOLICY : IMAGE_IDX_POLICY;
  1740. id = ((state & ACSDATA_STATE_DISABLED) != 0)? IMAGE_IDX_DISABLEDPOLICY : id;
  1741. m_pNode->SetData(TFS_DATA_IMAGEINDEX, id);
  1742. m_pNode->SetData(TFS_DATA_OPENIMAGEINDEX, id);
  1743. hr = m_pNode->ChangeNode(RESULT_PANE_CHANGE_ITEM);
  1744. //
  1745. L_ERR:
  1746. return hr;
  1747. }
  1748. STDMETHODIMP
  1749. CACSPolicyHandle::CreatePropertyPages
  1750. (
  1751. ITFSComponent * pComponent,
  1752. MMC_COOKIE cookie,
  1753. LPPROPERTYSHEETCALLBACK lpProvider,
  1754. LPDATAOBJECT pDataObject,
  1755. LONG_PTR handle
  1756. )
  1757. {
  1758. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1759. HRESULT hr = S_OK;
  1760. DWORD dwError;
  1761. CString strServiceName;
  1762. if (FAILED(hr))
  1763. return FALSE;
  1764. CACSPolicyElement* pObj = dynamic_cast<CACSPolicyElement*>(m_pDSObject);
  1765. CComPtr<CACSPolicyElement> spElement;
  1766. ASSERT(pObj);
  1767. spElement = pObj;
  1768. CHECK_HR(hr = spElement->Reopen());
  1769. try{
  1770. CPgPolicyGeneral* pPgGeneral = NULL;
  1771. CPgPolicyFlow* pPgFlow = NULL;
  1772. CPgPolicyAggregate* pPgAggr = NULL;
  1773. HPROPSHEETPAGE hPgGeneral = NULL;
  1774. HPROPSHEETPAGE hPgFlow = NULL;
  1775. HPROPSHEETPAGE hPgAggr = NULL;
  1776. // create a page manager for all the pages
  1777. CComObject<CACSPolicyPageManager>* pPageManager;
  1778. CHECK_HR(hr = CComObject<CACSPolicyPageManager>::CreateInstance(&pPageManager));
  1779. pPageManager->SetPolicyData(spElement, this);
  1780. pPageManager->SetMMCNotify(handle, (LPARAM)this);
  1781. //===============
  1782. // general page
  1783. pPgGeneral = new CPgPolicyGeneral((CACSPolicyElement*)spElement);
  1784. pPageManager->AddPage(pPgGeneral); // add a page to the manager
  1785. pPageManager->SetGeneralPage(pPgGeneral);
  1786. pPageManager->SetBranchFlag(m_nBranchFlag);
  1787. // tell MMC to hook the proc because we are running on a separate,
  1788. // non MFC thread.
  1789. // change callback function to delete itself when the property sheet is released
  1790. pPgGeneral->SetSelfDeleteCallback();
  1791. // if there are specil operation on Cancel, make sure the page is dirty
  1792. // even when user just click on OK, OnApply is still called.
  1793. if(m_bDeleteUponCancel)
  1794. pPgGeneral->SetModified();
  1795. MMCPropPageCallback(&pPgGeneral->m_psp);
  1796. hPgGeneral = ::CreatePropertySheetPage(&pPgGeneral->m_psp);
  1797. if(hPgGeneral == NULL)
  1798. CHECK_HR(hr = E_UNEXPECTED);
  1799. lpProvider->AddPage(hPgGeneral);
  1800. //=====================
  1801. // Flow page
  1802. pPgFlow = new CPgPolicyFlow((CACSPolicyElement*)spElement);
  1803. pPageManager->AddPage(pPgFlow); // add a page to the manager
  1804. // tell MMC to hook the proc because we are running on a separate,
  1805. // non MFC thread.
  1806. // change callback function to delete itself when the property sheet is released
  1807. pPgFlow->SetSelfDeleteCallback();
  1808. MMCPropPageCallback(&pPgFlow->m_psp);
  1809. hPgFlow = ::CreatePropertySheetPage(&pPgFlow->m_psp);
  1810. if(hPgFlow == NULL)
  1811. CHECK_HR(hr = E_UNEXPECTED);
  1812. lpProvider->AddPage(hPgFlow);
  1813. // set branch info and ..
  1814. pPgFlow->m_nBranchFlag = m_nBranchFlag;
  1815. pPgFlow->m_pGeneralPage = pPgGeneral;
  1816. //=====================
  1817. // Aggr page
  1818. pPgAggr = new CPgPolicyAggregate((CACSPolicyElement*)spElement);
  1819. pPageManager->AddPage(pPgAggr); // add a page to the manager
  1820. // tell MMC to hook the proc because we are running on a separate,
  1821. // non MFC thread.
  1822. // change callback function to delete itself when the property sheet is released
  1823. pPgAggr->SetSelfDeleteCallback();
  1824. MMCPropPageCallback(&pPgAggr->m_psp);
  1825. hPgAggr = ::CreatePropertySheetPage(&pPgAggr->m_psp);
  1826. if(hPgAggr == NULL)
  1827. CHECK_HR(hr = E_UNEXPECTED);
  1828. lpProvider->AddPage(hPgAggr);
  1829. // set branch info and ..
  1830. pPgAggr->m_nBranchFlag = m_nBranchFlag;
  1831. pPgAggr->m_pGeneralPage = pPgGeneral;
  1832. }catch(CMemoryException&){
  1833. CHECK_HR(hr = E_OUTOFMEMORY);
  1834. }
  1835. L_ERR:
  1836. if FAILED(hr)
  1837. ReportError(hr, IDS_ERR_PROPERTYPAGE, NULL);
  1838. return hr;
  1839. }
  1840. ///////////////////////////////////////////////////////////////////////////////