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.

1840 lines
56 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 2000
  4. Module Name:
  5. PoliciesNode.cpp
  6. Abstract:
  7. Implementation file for the CPoliciesNode class.
  8. Revision History:
  9. mmaguire 12/15/97 - created
  10. --*/
  11. //////////////////////////////////////////////////////////////////////////////
  12. //////////////////////////////////////////////////////////////////////////////
  13. // BEGIN INCLUDES
  14. //
  15. // standard includes:
  16. //
  17. #include "Precompiled.h"
  18. //
  19. // where we can find declaration for main class in this file:
  20. //
  21. #include "PoliciesNode.h"
  22. #include "ComponentData.h" // this must be included before NodeWithResultChildrenList.cpp
  23. #include "Component.h" // this must be included before NodeWithResultChildrenList.cpp
  24. #include "NodeWithResultChildrenList.cpp" // Implementation of template class.
  25. //
  26. //
  27. // where we can find declarations needed in this file:
  28. //
  29. #include <time.h>
  30. #include "PoliciesPage1.h"
  31. #include "PolicyLocDlg.h"
  32. #include "LocWarnDlg.h"
  33. #include "PolicyNode.h"
  34. #include "MachineNode.h"
  35. #include "mmcUtility.h"
  36. #include "NapUtil.h"
  37. #include "SafeArray.h"
  38. #include "ChangeNotification.h"
  39. #include "sdoias.h"
  40. //
  41. // END INCLUDES
  42. //////////////////////////////////////////////////////////////////////////////
  43. //////////////////////////////////////////////////////////////////////////////
  44. // CPoliciesNode::CPoliciesNode
  45. //
  46. //////////////////////////////////////////////////////////////////////////////
  47. CPoliciesNode::CPoliciesNode(
  48. CSnapInItem* pParentNode,
  49. LPTSTR pszServerAddress,
  50. bool fExtendingIAS
  51. )
  52. :CNodeWithResultChildrenList<CPoliciesNode, CPolicyNode, CMeritNodeArray<CPolicyNode*>, CComponentData, CComponent> (pParentNode, (!fExtendingIAS)?RAS_HELP_INDEX:0),
  53. m_fExtendingIAS(fExtendingIAS),
  54. m_serverType(unknown)
  55. {
  56. TRACE_FUNCTION("CPoliciesNode::CPoliciesNode");
  57. TCHAR lpszName[NAP_MAX_STRING];
  58. int nLoadStringResult;
  59. // always initialized to not connected and local
  60. m_fSdoConnected = FALSE;
  61. m_fUseDS = FALSE;
  62. m_fDSAvailable = FALSE;
  63. try
  64. {
  65. // Set the display name for this object
  66. nLoadStringResult = LoadString( _Module.GetResourceInstance(),
  67. IDS_POLICIES_NODE,
  68. lpszName,
  69. NAP_MAX_STRING
  70. );
  71. _ASSERT( nLoadStringResult > 0 );
  72. m_bstrDisplayName = lpszName;
  73. // In IComponentData::Initialize, we are asked to inform MMC of
  74. // the icons we would like to use for the scope pane.
  75. // Here we store an index to which of these images we
  76. // want to be used to display this node
  77. m_scopeDataItem.nImage = IDBI_NODE_POLICIES_OK_CLOSED;
  78. m_scopeDataItem.nOpenImage = IDBI_NODE_POLICIES_OK_OPEN;
  79. // initialize the machine name
  80. m_pszServerAddress = pszServerAddress;
  81. }
  82. catch(...)
  83. {
  84. throw;
  85. }
  86. }
  87. //////////////////////////////////////////////////////////////////////////////
  88. /*++
  89. CPoliciesNode::~CPoliciesNode
  90. Destructor
  91. --*/
  92. //////////////////////////////////////////////////////////////////////////////
  93. CPoliciesNode::~CPoliciesNode()
  94. {
  95. TRACE_FUNCTION("CPoliciesNode::~CPoliciesNode");
  96. }
  97. //////////////////////////////////////////////////////////////////////////////
  98. /*++
  99. CPoliciesNode::GetResultPaneColInfo
  100. See CSnapinNode::GetResultPaneColInfo (which this method overrides) for detailed info.
  101. --*/
  102. //////////////////////////////////////////////////////////////////////////////
  103. OLECHAR* CPoliciesNode::GetResultPaneColInfo(int nCol)
  104. {
  105. TRACE_FUNCTION("CPoliciesNode::GetResultPaneColInfo");
  106. if (nCol == 0 && m_bstrDisplayName != NULL)
  107. return m_bstrDisplayName;
  108. return NULL;
  109. }
  110. //////////////////////////////////////////////////////////////////////////////
  111. /*++
  112. CPoliciesNode::SetVerbs
  113. See CSnapinNode::SetVerbs (which this method overrides) for detailed info.
  114. --*/
  115. //////////////////////////////////////////////////////////////////////////////
  116. HRESULT CPoliciesNode::SetVerbs( IConsoleVerb * pConsoleVerb )
  117. {
  118. TRACE_FUNCTION("CPoliciesNode::SetVerbs");
  119. return pConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE );
  120. // We don't want the user deleting or renaming this node, so we
  121. // don't set the MMC_VERB_RENAME or MMC_VERB_DELETE verbs.
  122. // By default, when a node becomes selected, these are disabled.
  123. // hr = pConsoleVerb->SetVerbState( MMC_VERB_OPEN, ENABLED, TRUE );
  124. // DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "SetVerState() returns %x", hr);
  125. // hr = pConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN );
  126. // DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "SetDefaultVerb() returns %x", hr);
  127. }
  128. //////////////////////////////////////////////////////////////////////////////
  129. /*++
  130. CPoliciesNode::InsertColumns
  131. See CNodeWithResultChildrenList::InsertColumns (which this method overrides)
  132. for detailed info.
  133. --*/
  134. //////////////////////////////////////////////////////////////////////////////
  135. HRESULT CPoliciesNode::InsertColumns( IHeaderCtrl* pHeaderCtrl )
  136. {
  137. TRACE_FUNCTION("CPoliciesNode::OnShowInsertColumns");
  138. TCHAR tzColumnTitle1[IAS_MAX_STRING];
  139. TCHAR tzColumnTitle2[IAS_MAX_STRING];
  140. TCHAR tzColumnTitle3[IAS_MAX_STRING];
  141. HRESULT hr = S_OK;
  142. HINSTANCE hInstance = _Module.GetResourceInstance();
  143. int iRes;
  144. iRes = LoadString(hInstance, IDS_POLICY_COLUMN_TITLE1, tzColumnTitle1, IAS_MAX_STRING );
  145. _ASSERT( iRes > 0 );
  146. iRes = LoadString(hInstance, IDS_POLICY_COLUMN_TITLE2, tzColumnTitle2, IAS_MAX_STRING );
  147. _ASSERT( iRes > 0 );
  148. hr = pHeaderCtrl->InsertColumn( 0, tzColumnTitle1, 0, 260 );
  149. _ASSERT( S_OK == hr );
  150. hr = pHeaderCtrl->InsertColumn( 1, tzColumnTitle2, 0, 50 );
  151. _ASSERT( S_OK == hr );
  152. return hr;
  153. }
  154. //////////////////////////////////////////////////////////////////////////////
  155. /*++
  156. CPoliciesNode::UpdateMenuState
  157. --*/
  158. //////////////////////////////////////////////////////////////////////////////
  159. void CPoliciesNode::UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags)
  160. {
  161. TRACE_FUNCTION("CPoliciesNode::UpdateMenuState");
  162. // Check for preconditions:
  163. // None.
  164. //
  165. // disable "New Policy" and "Change Policy Location" menu when
  166. // not connected
  167. //
  168. if ( id == ID_MENUITEM_POLICIES_TOP__POLICY_LOCATION ||
  169. id == ID_MENUITEM_POLICIES_TOP__NEW_POLICY ||
  170. id == ID_MENUITEM_POLICIES_NEW__POLICY )
  171. {
  172. if (!m_fSdoConnected )
  173. {
  174. * flags = MFS_GRAYED;
  175. return;
  176. }
  177. else
  178. {
  179. *flags = MFS_ENABLED;
  180. return;
  181. }
  182. }
  183. return;
  184. }
  185. //////////////////////////////////////////////////////////////////////////////
  186. /*++
  187. CPoliciesNode::OnRefresh
  188. See CSnapinNode::OnRefresh (which this method overrides) for detailed info.
  189. --*/
  190. //////////////////////////////////////////////////////////////////////////////
  191. HRESULT CPoliciesNode::OnRefresh(
  192. LPARAM arg
  193. , LPARAM param
  194. , IComponentData * pComponentData
  195. , IComponent * pComponent
  196. , DATA_OBJECT_TYPES type
  197. )
  198. {
  199. HRESULT hr = S_OK;
  200. CWaitCursor WC;
  201. CComPtr<IConsole> spConsole;
  202. // We need IConsole
  203. if( pComponentData != NULL )
  204. {
  205. spConsole = ((CComponentData*)pComponentData)->m_spConsole;
  206. }
  207. else
  208. {
  209. spConsole = ((CComponent*)pComponent)->m_spConsole;
  210. }
  211. _ASSERTE( spConsole != NULL );
  212. // if there is any property page open
  213. int c = m_ResultChildrenList.GetSize();
  214. while ( c-- > 0)
  215. {
  216. CPolicyNode* pSub = m_ResultChildrenList[c];
  217. // Call our base class's method to remove the child from its list.
  218. // The RemoveChild method takes care of removing this node from the
  219. // UI's list of nodes under the parent and performing a refresh of all relevant views.
  220. // This returns S_OK if a property sheet for this object already exists
  221. // and brings that property sheet to the foreground.
  222. // It returns S_FALSE if the property sheet wasn't found.
  223. hr = BringUpPropertySheetForNode(
  224. pSub
  225. , pComponentData
  226. , pComponent
  227. , spConsole
  228. );
  229. if( S_OK == hr )
  230. {
  231. // We found a property sheet already up for this node.
  232. ShowErrorDialog( NULL, IDS_ERROR_CLOSE_PROPERTY_SHEET, NULL, hr, 0, spConsole );
  233. return hr;
  234. }
  235. }
  236. // if no property page is open, delete all the result node
  237. RemoveChildrenNoRefresh();
  238. // reload SDO from
  239. hr = ((CMachineNode *) m_pParentNode)->DataRefresh();
  240. // refresh the node
  241. hr = CNodeWithResultChildrenList< CPoliciesNode, CPolicyNode, CMeritNodeArray<CPolicyNode*>, CComponentData, CComponent >::OnRefresh(
  242. arg, param, pComponentData, pComponent, type);
  243. return hr;
  244. }
  245. //////////////////////////////////////////////////////////////////////////////
  246. /*++
  247. CPoliciesNode::PopulateResultChildrenList
  248. See CNodeWithResultChildrenList::PopulateResultChildrenList (which this method overrides)
  249. for detailed info.
  250. --*/
  251. //////////////////////////////////////////////////////////////////////////////
  252. HRESULT CPoliciesNode::PopulateResultChildrenList( void )
  253. {
  254. TRACE_FUNCTION("CPoliciesNode::PopulateResultChildrenList");
  255. HRESULT hr = S_OK;
  256. CComPtr<IUnknown> spUnknown;
  257. CComPtr<IEnumVARIANT> spEnumVariant;
  258. CComVariant spVariant;
  259. long ulCount;
  260. ULONG ulCountReceived;
  261. if ( !m_fSdoConnected )
  262. {
  263. return E_FAIL;
  264. }
  265. if( m_spPoliciesCollectionSdo == NULL )
  266. {
  267. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "NULL policies collection");
  268. return S_FALSE; // Is there a better error to return here?
  269. }
  270. //
  271. // has the policies been populated already?
  272. //
  273. if ( m_bResultChildrenListPopulated )
  274. {
  275. return S_OK;
  276. }
  277. //
  278. // how many policies do we have right now?
  279. //
  280. m_spPoliciesCollectionSdo->get_Count( & ulCount );
  281. DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "Number of policies: %d", ulCount);
  282. if( ulCount > 0 )
  283. {
  284. //
  285. // Get the enumerator for the policies collection.
  286. //
  287. hr = m_spPoliciesCollectionSdo->get__NewEnum( (IUnknown **) & spUnknown );
  288. if ( FAILED(hr) )
  289. {
  290. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "get__NewEnum() failed, err = %x", hr);
  291. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_ENUMPOLICY, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  292. return hr;
  293. }
  294. hr = spUnknown->QueryInterface( IID_IEnumVARIANT, (void **) &spEnumVariant );
  295. if ( FAILED(hr) )
  296. {
  297. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "QueryInterface(IEnumVARIANT) failed, err = %x", hr);
  298. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_QUERYINTERFACE, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  299. return hr;
  300. }
  301. _ASSERTE( spEnumVariant != NULL );
  302. spUnknown.Release();
  303. // Get the first item.
  304. hr = spEnumVariant->Next( 1, & spVariant, &ulCountReceived );
  305. while( SUCCEEDED( hr ) && ulCountReceived == 1 )
  306. {
  307. _ASSERTE( spVariant.vt == VT_DISPATCH );
  308. _ASSERTE( spVariant.pdispVal != NULL );
  309. CComPtr<ISdo> spPolicySdo;
  310. CComPtr<ISdo> spProfileSdo;
  311. CPolicyNode* pPolicyNode;
  312. CComVariant varPolicyName;
  313. CComVariant varProfileName;
  314. //
  315. // before we create the policy object, we need to make sure the corresponding
  316. // profile object is also there
  317. //
  318. hr = spVariant.pdispVal->QueryInterface( IID_ISdo, (void **) &spPolicySdo );
  319. _ASSERTE( SUCCEEDED( hr ) );
  320. //
  321. // try to find the profile that's associated with this policy sdo
  322. //
  323. hr = spPolicySdo->GetProperty(PROPERTY_POLICY_PROFILE_NAME, &varProfileName);
  324. if ( SUCCEEDED(hr) )
  325. {
  326. // found the profile name from the sdo, search whether it
  327. // is in the profile collection
  328. _ASSERTE( V_VT(&varProfileName) == VT_BSTR );
  329. ATLTRACE(_T("PROFILE NAME:%ws\n"), V_BSTR(&varProfileName) );
  330. DebugTrace(DEBUG_NAPMMC_POLICIESNODE,
  331. "Profile name for this policy: %ws",
  332. V_BSTR(&varProfileName)
  333. );
  334. CComPtr<IDispatch> spDispatch;
  335. spDispatch.p = NULL;
  336. hr = m_spProfilesCollectionSdo->Item(&varProfileName, &spDispatch.p);
  337. if ( !SUCCEEDED(hr) )
  338. {
  339. // can't find this profile
  340. ErrorTrace(ERROR_NAPMMC_POLICIESNODE,
  341. "profile %ws not found, err = %x",
  342. V_BSTR(&varProfileName),
  343. hr
  344. );
  345. ATLTRACE(_T("PROFILE not found in the profile collection!!!!\n"));
  346. ShowErrorDialog( NULL, IDS_ERROR_PROFILE_NOEXIST, V_BSTR(&varProfileName), S_OK, USE_DEFAULT, GetComponentData()->m_spConsole );
  347. goto get_next_policy;
  348. }
  349. _ASSERTE( spDispatch.p );
  350. hr = spDispatch->QueryInterface(IID_ISdo, (VOID**)(&spProfileSdo) );
  351. if ( ! SUCCEEDED(hr) )
  352. {
  353. // invalid profile SDO pointer
  354. ErrorTrace(ERROR_NAPMMC_POLICIESNODE,
  355. "can't get the ISdo pointer for this profile , err = %x",
  356. hr
  357. );
  358. ATLTRACE(_T("can't get profile SDO pointer!!!!\n"));
  359. ShowErrorDialog( NULL, IDS_ERROR_PROFILE_NOEXIST, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  360. goto get_next_policy;
  361. }
  362. }
  363. else
  364. {
  365. //
  366. // can't find profile name for this policy
  367. // Which means the information in this policy is corrupted
  368. //
  369. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "can't get profile name for this policy, err = %x", hr);
  370. //
  371. // let's get the policy name so we can report a meaningful error msg
  372. //
  373. hr = spPolicySdo->GetProperty(PROPERTY_SDO_NAME, &varPolicyName);
  374. if ( SUCCEEDED(hr) )
  375. {
  376. ATLTRACE(_T("PROFILE not found in the profile collection!!!!\n"));
  377. ShowErrorDialog( NULL, IDS_ERROR_NO_PROFILE_NAME, V_BSTR(&varPolicyName), S_OK, USE_DEFAULT, GetComponentData()->m_spConsole );
  378. }
  379. else
  380. {
  381. // can't even get the policy name
  382. ShowErrorDialog( NULL, IDS_ERROR_NO_PROFILE_NAME, NULL, S_OK, USE_DEFAULT, GetComponentData()->m_spConsole );
  383. }
  384. goto get_next_policy;
  385. }
  386. //
  387. // now we have both profile and policy
  388. //
  389. // Create a new node UI object to represent the sdo object.
  390. pPolicyNode = new CPolicyNode( this, // always a pointer to itself
  391. m_pszServerAddress, // server address
  392. &m_AttrList, // list of all attributes
  393. FALSE, // not a brand new node
  394. m_fUseDS, // use DS or not??
  395. IsWin2kServer() // is a Win2k machine?
  396. );
  397. if( NULL == pPolicyNode )
  398. {
  399. hr = HRESULT_FROM_WIN32(GetLastError());
  400. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't create policy node, err = %x", hr);
  401. ShowErrorDialog( NULL, IDS_ERROR_CANT_CREATE_POLICY, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  402. goto get_next_policy;
  403. }
  404. // Pass the newly created node its SDO pointer.
  405. hr = pPolicyNode->SetSdo( spPolicySdo
  406. , m_spDictionarySdo
  407. , spProfileSdo
  408. , m_spProfilesCollectionSdo
  409. , m_spPoliciesCollectionSdo
  410. , m_spSdoServiceControl
  411. );
  412. _ASSERTE( SUCCEEDED( hr ) );
  413. hr = pPolicyNode->LoadSdoData();
  414. DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "pPoliciNode->LoadSdoData() returned %x", hr);
  415. // Add the newly created node to the list of Policys.
  416. AddChildToList(pPolicyNode);
  417. if ( !SUCCEEDED(hr) )
  418. {
  419. //
  420. // this is actually a hack: we are just trying to save coding work
  421. // because we can use RemoveChild() for this bad object so all the SDO
  422. // pointers can also be removed
  423. //
  424. RemoveChild(pPolicyNode);
  425. }
  426. get_next_policy: // now get the next policy
  427. // Clear the variant of whatever it had --
  428. // this will release any data associated with it.
  429. spVariant.Clear();
  430. // Get the next item.
  431. hr = spEnumVariant->Next( 1, & spVariant, &ulCountReceived );
  432. }
  433. }
  434. else
  435. {
  436. // There are no items in the enumeration
  437. // Do nothing.
  438. }
  439. //
  440. // now we need to reset the merit value of every child node, for example,
  441. // maybe there're only two children, with merit value of 20 and 100. We need
  442. // to reset them to 1 and 2.
  443. //
  444. for (int iIndex=0; iIndex<m_ResultChildrenList.GetSize(); iIndex++)
  445. {
  446. m_ResultChildrenList[iIndex]->SetMerit(iIndex+1);
  447. }
  448. m_bResultChildrenListPopulated = TRUE;
  449. return hr;
  450. }
  451. //////////////////////////////////////////////////////////////////////////////
  452. /*++
  453. CPoliciesNode::GetComponentData
  454. This method returns our unique CComponentData object representing the scope
  455. pane of this snapin.
  456. It relies upon the fact that each node has a pointer to its parent,
  457. except for the root node, which instead has a member variable pointing
  458. to CComponentData.
  459. This would be a useful function to use if, for example, you need a reference
  460. to some IConsole but you weren't passed one. You can use GetComponentData
  461. and then use the IConsole pointer which is a member variable of our
  462. CComponentData object.
  463. --*/
  464. //////////////////////////////////////////////////////////////////////////////
  465. CComponentData * CPoliciesNode::GetComponentData( void )
  466. {
  467. TRACE_FUNCTION("CPoliciesNode::GetComponentData");
  468. return ((CMachineNode *) m_pParentNode)->GetComponentData();
  469. }
  470. //+---------------------------------------------------------------------------
  471. //
  472. // Function: SetSdo
  473. //
  474. // Class: CPoliciesNode
  475. //
  476. // Synopsis: Initialize the CPoliciesNode using the SDO pointers
  477. //
  478. // Arguments: ISdo* pMachineSdo - Server SDO
  479. // ISdoDictionaryOld* pDictionarySdo - Sdo Dictionary
  480. // BOOL fSdoConnected - is connection successful?
  481. // BOOL fUseDS - is the service using DS?
  482. // BOOL fDSAvailable - is DS available?
  483. //
  484. // Returns: HRESULT - how the initialization goes
  485. //
  486. // History: Created byao 2/6/98 8:03:12 PM
  487. //
  488. //+---------------------------------------------------------------------------
  489. HRESULT CPoliciesNode::SetSdo( ISdo* pServiceSdo,
  490. ISdoDictionaryOld* pDictionarySdo,
  491. BOOL fSdoConnected,
  492. BOOL fUseDS,
  493. BOOL fDSAvailable
  494. )
  495. {
  496. TRACE_FUNCTION("CPoliciesNode::SetSdo");
  497. HRESULT hr = S_OK;
  498. _ASSERTE( pServiceSdo != NULL );
  499. _ASSERTE( pDictionarySdo != NULL );
  500. // Initialize all the data members
  501. m_fSdoConnected = fSdoConnected;
  502. m_fUseDS = fUseDS;
  503. m_fDSAvailable = fDSAvailable;
  504. // Save away the interface pointers.
  505. m_spDictionarySdo = pDictionarySdo;
  506. m_spServiceSdo = pServiceSdo;
  507. // Get the ISdoServiceControl interface.
  508. hr = m_spServiceSdo->QueryInterface( IID_ISdoServiceControl, (void **) &m_spSdoServiceControl );
  509. if ( FAILED(hr) )
  510. {
  511. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't get service control interface, err = %x", hr);
  512. m_spSdoServiceControl = NULL;
  513. return hr;
  514. }
  515. // We just copied an interface pointer into a smart pointer -- need to AddRef manually.
  516. // 39470 *RRAS snapin mmc process does not get shut down upon closing if F1 help is used.
  517. // m_spSdoServiceControl->AddRef();
  518. // Make sure the name of the policies node will reflect what
  519. // data source we are using for the policies.
  520. // We weren't passed an IConsole pointer here, so
  521. // we use the one we saved in our CComponentData object.
  522. CComponentData * pComponentData = GetComponentData();
  523. _ASSERTE( pComponentData != NULL );
  524. _ASSERTE( pComponentData->m_spConsole != NULL );
  525. SetName( m_fUseDS, m_pszServerAddress, pComponentData->m_spConsole );
  526. // Get polices and profiles SDO.
  527. m_spProfilesCollectionSdo = NULL;
  528. m_spPoliciesCollectionSdo = NULL;
  529. hr = ::GetSdoInterfaceProperty(
  530. m_spServiceSdo,
  531. PROPERTY_IAS_PROFILES_COLLECTION,
  532. IID_ISdoCollection,
  533. (void **) &m_spProfilesCollectionSdo);
  534. if( FAILED(hr) || ! m_spProfilesCollectionSdo )
  535. {
  536. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't get profiles collection, err = %x", hr);
  537. m_spProfilesCollectionSdo = NULL;
  538. return hr;
  539. }
  540. // policies collection SDO
  541. hr = ::GetSdoInterfaceProperty(
  542. m_spServiceSdo,
  543. PROPERTY_IAS_POLICIES_COLLECTION,
  544. IID_ISdoCollection,
  545. (void **) &m_spPoliciesCollectionSdo);
  546. if( FAILED(hr) || ! m_spPoliciesCollectionSdo )
  547. {
  548. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't get policies collection, err = %x", hr);
  549. m_spPoliciesCollectionSdo = NULL;
  550. return hr;
  551. }
  552. // Get the interface pointers required for the vendor list.
  553. // First need RADIUS protocol object.
  554. CComPtr<ISdo> spSdoRadiusProtocol;
  555. hr = ::SDOGetSdoFromCollection( m_spServiceSdo
  556. , PROPERTY_IAS_PROTOCOLS_COLLECTION
  557. , PROPERTY_COMPONENT_ID
  558. , IAS_PROTOCOL_MICROSOFT_RADIUS
  559. , &spSdoRadiusProtocol
  560. );
  561. if( FAILED(hr) || ! spSdoRadiusProtocol )
  562. {
  563. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't get RADIUS protocol object, err = %x", hr);
  564. return hr;
  565. }
  566. CComPtr<ISdoCollection> spSdoVendors;
  567. hr = ::GetSdoInterfaceProperty(
  568. spSdoRadiusProtocol
  569. , PROPERTY_RADIUS_VENDORS_COLLECTION
  570. , IID_ISdoCollection
  571. , (void **) &spSdoVendors
  572. );
  573. if ( FAILED(hr) || ! spSdoVendors )
  574. {
  575. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't get vendors collection, err = %x", hr);
  576. return hr;
  577. }
  578. // Create and initialize the IASNASVendors object.
  579. // This is a singleton COM object which we will initialize here
  580. // and which will then be used by other clients in different parts of the UI.
  581. hr = CoCreateInstance( CLSID_IASNASVendors, NULL, CLSCTX_INPROC_SERVER, IID_IIASNASVendors, (LPVOID *) &m_spIASNASVendors );
  582. if( SUCCEEDED(hr) )
  583. {
  584. HRESULT hrTemp = m_spIASNASVendors->InitFromSdo(spSdoVendors);
  585. }
  586. // Initialize the attribute list from the dictionary.
  587. hr = m_AttrList.Init(m_spDictionarySdo);
  588. DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "m_AttrList->Init() returned %x", hr);
  589. return hr;
  590. }
  591. //+---------------------------------------------------------------------------
  592. //
  593. // Function: DataRefresh -- to support
  594. //
  595. // Class: CPoliciesNode
  596. //
  597. // Synopsis: Initialize the CPoliciesNode using the SDO pointers
  598. //
  599. // Arguments: ISdo* pMachineSdo - Server SDO
  600. // ISdoDictionaryOld* pDictionarySdo - Sdo Dictionary
  601. // Returns: HRESULT - how the initialization goes
  602. //
  603. // History: Created byao 2/6/98 8:03:12 PM
  604. //
  605. //+---------------------------------------------------------------------------
  606. HRESULT CPoliciesNode::DataRefresh( ISdo* pServiceSdo,
  607. ISdoDictionaryOld* pDictionarySdo
  608. )
  609. {
  610. HRESULT hr = S_OK;
  611. _ASSERTE( pServiceSdo != NULL );
  612. _ASSERTE( pDictionarySdo != NULL );
  613. // Save away the interface pointers.
  614. m_spDictionarySdo.Release();
  615. m_spServiceSdo.Release();
  616. m_spDictionarySdo = pDictionarySdo;
  617. m_spServiceSdo = pServiceSdo;
  618. // Get the ISdoServiceControl interface.
  619. m_spSdoServiceControl.Release();
  620. hr = m_spServiceSdo->QueryInterface( IID_ISdoServiceControl, (void **) &m_spSdoServiceControl );
  621. if ( FAILED(hr) )
  622. return hr;
  623. // Make sure the name of the policies node will reflect what
  624. // data source we are using for the policies.
  625. // We weren't passed an IConsole pointer here, so
  626. // we use the one we saved in our CComponentData object.
  627. CComponentData * pComponentData = GetComponentData();
  628. _ASSERTE( pComponentData != NULL );
  629. _ASSERTE( pComponentData->m_spConsole != NULL );
  630. // Get polices and profiles SDO.
  631. m_spProfilesCollectionSdo = NULL;
  632. m_spPoliciesCollectionSdo = NULL;
  633. m_spProfilesCollectionSdo.Release();
  634. hr = ::GetSdoInterfaceProperty(
  635. m_spServiceSdo,
  636. PROPERTY_IAS_PROFILES_COLLECTION,
  637. IID_ISdoCollection,
  638. (void **) &m_spProfilesCollectionSdo);
  639. if( FAILED(hr) || ! m_spProfilesCollectionSdo )
  640. {
  641. return hr;
  642. }
  643. // policies collection SDO
  644. m_spPoliciesCollectionSdo.Release();
  645. hr = ::GetSdoInterfaceProperty(
  646. m_spServiceSdo,
  647. PROPERTY_IAS_POLICIES_COLLECTION,
  648. IID_ISdoCollection,
  649. (void **) &m_spPoliciesCollectionSdo);
  650. if( FAILED(hr) || ! m_spPoliciesCollectionSdo )
  651. {
  652. return hr;
  653. }
  654. return hr;
  655. }
  656. //+---------------------------------------------------------------------------
  657. //
  658. // Function: NormalizeMerit
  659. //
  660. // Class: CPoliciesNode
  661. //
  662. // Synopsis: move up the merit value of a child node
  663. //
  664. // Arguments: CChildNode * pChildNode - the pointer to the child node
  665. //
  666. // Returns: HRESULT;
  667. //
  668. // History: Created byao 2/9/98 2:53:10 PM
  669. //
  670. //+---------------------------------------------------------------------------
  671. HRESULT CPoliciesNode::NormalizeMerit( CPolicyNode* pChildNode )
  672. {
  673. TRACE_FUNCTION("CPoliciesNode::MoveUpChild");
  674. // Check for preconditions:
  675. ATLASSERT(pChildNode);
  676. // None.
  677. HRESULT hr = S_OK;
  678. if( m_ResultChildrenList.NormalizeMerit( pChildNode ) )
  679. {
  680. //
  681. // We weren't passed an IConsole pointer here, so
  682. // we use the one we saved in out CComponentData object.
  683. // Update all views
  684. //
  685. CComponentData * pComponentData = GetComponentData();
  686. _ASSERTE( pComponentData != NULL );
  687. _ASSERTE( pComponentData->m_spConsole != NULL );
  688. // We pass in a pointer to 'this' because we want each
  689. // of our CComponent objects to update its result pane
  690. // view if 'this' node is the same as the saved currently
  691. // selected node.
  692. // Make MMC update this node in all views.
  693. CChangeNotification *pChangeNotification = new CChangeNotification();
  694. pChangeNotification->m_dwFlags = CHANGE_RESORT_PARENT;
  695. pChangeNotification->m_pNode = pChildNode;
  696. pChangeNotification->m_pParentNode = this;
  697. hr = pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0);
  698. pChangeNotification->Release();
  699. // Tell the service to reload data.
  700. HRESULT hrTemp = m_spSdoServiceControl->ResetService();
  701. if( FAILED( hrTemp ) )
  702. {
  703. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "ISdoServiceControl::ResetService() failed, err = %x", hrTemp);
  704. }
  705. }
  706. else
  707. {
  708. // something strange has happened
  709. _ASSERTE( FALSE );
  710. hr = S_FALSE;
  711. }
  712. return hr;
  713. }
  714. //+---------------------------------------------------------------------------
  715. //
  716. // Function: MoveUpChild
  717. //
  718. // Class: CPoliciesNode
  719. //
  720. // Synopsis: move up the merit value of a child node
  721. //
  722. // Arguments: CChildNode * pChildNode - the pointer to the child node
  723. //
  724. // Returns: HRESULT;
  725. //
  726. // History: Created byao 2/9/98 2:53:10 PM
  727. //
  728. //+---------------------------------------------------------------------------
  729. HRESULT CPoliciesNode::MoveUpChild( CPolicyNode* pChildNode )
  730. {
  731. TRACE_FUNCTION("CPoliciesNode::MoveUpChild");
  732. // Check for preconditions:
  733. ATLASSERT(pChildNode);
  734. // None.
  735. HRESULT hr = S_OK;
  736. if( m_ResultChildrenList.MoveUp( pChildNode ) )
  737. {
  738. //
  739. // We weren't passed an IConsole pointer here, so
  740. // we use the one we saved in out CComponentData object.
  741. // Update all views
  742. //
  743. CComponentData * pComponentData = GetComponentData();
  744. _ASSERTE( pComponentData != NULL );
  745. _ASSERTE( pComponentData->m_spConsole != NULL );
  746. // We pass in a pointer to 'this' because we want each
  747. // of our CComponent objects to update its result pane
  748. // view if 'this' node is the same as the saved currently
  749. // selected node.
  750. // Make MMC update this node in all views.
  751. CChangeNotification *pChangeNotification = new CChangeNotification();
  752. pChangeNotification->m_dwFlags = CHANGE_RESORT_PARENT;
  753. pChangeNotification->m_pNode = pChildNode;
  754. pChangeNotification->m_pParentNode = this;
  755. hr = pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0);
  756. pChangeNotification->Release();
  757. // Tell the service to reload data.
  758. HRESULT hrTemp = m_spSdoServiceControl->ResetService();
  759. if( FAILED( hrTemp ) )
  760. {
  761. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "ISdoServiceControl::ResetService() failed, err = %x", hrTemp);
  762. }
  763. }
  764. else
  765. {
  766. // something strange has happened
  767. _ASSERTE( FALSE );
  768. hr = S_FALSE;
  769. }
  770. return hr;
  771. }
  772. //+---------------------------------------------------------------------------
  773. //
  774. // Function: MoveDownChild
  775. //
  776. // Class: CPoliciesNode
  777. //
  778. // Synopsis: move down the merit value of a child node
  779. //
  780. // Arguments: CChildNode * pChildNode - the pointer to the child node
  781. //
  782. // Returns: HRESULT;
  783. //
  784. // History: Created byao 2/9/98 2:53:10 PM
  785. //
  786. //+---------------------------------------------------------------------------
  787. HRESULT CPoliciesNode::MoveDownChild( CPolicyNode* pChildNode )
  788. {
  789. TRACE_FUNCTION("CPoliciesNode::MoveDownChild");
  790. // Check for preconditions:
  791. ATLASSERT(pChildNode);
  792. // None.
  793. HRESULT hr = S_OK;
  794. if( m_ResultChildrenList.MoveDown( pChildNode ) )
  795. {
  796. //
  797. // We weren't passed an IConsole pointer here, so
  798. // we use the one we saved in out CComponentData object.
  799. // Update all views
  800. //
  801. CComponentData * pComponentData = GetComponentData();
  802. _ASSERTE( pComponentData != NULL );
  803. _ASSERTE( pComponentData->m_spConsole != NULL );
  804. // Make MMC update this node in all views.
  805. CChangeNotification *pChangeNotification = new CChangeNotification();
  806. pChangeNotification->m_dwFlags = CHANGE_RESORT_PARENT;
  807. pChangeNotification->m_pNode = pChildNode;
  808. pChangeNotification->m_pParentNode = this;
  809. hr = pComponentData->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0);
  810. pChangeNotification->Release();
  811. // Tell the service to reload data.
  812. HRESULT hrTemp = m_spSdoServiceControl->ResetService();
  813. if( FAILED( hrTemp ) )
  814. {
  815. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "ISdoServiceControl::ResetService() failed, err = %x", hrTemp);
  816. }
  817. }
  818. else
  819. {
  820. // something strange has happened
  821. _ASSERTE( FALSE );
  822. hr = S_FALSE;
  823. }
  824. return hr;
  825. }
  826. //+---------------------------------------------------------------------------
  827. //
  828. // Function: CPoliciesNode::OnNewPolicy
  829. //
  830. // Synopsis: to add a policy node
  831. //
  832. // Arguments: IUnknown *pUnknown - IUnknown pointer passed to the snap-in node
  833. //
  834. // Returns: HRESULT -
  835. //
  836. // History: Created Header byao 2/24/98 1:45:12 AM
  837. //
  838. //+---------------------------------------------------------------------------
  839. HRESULT CPoliciesNode::OnNewPolicy(bool &bHandled, CSnapInObjectRootBase* pObj )
  840. {
  841. TRACE_FUNCTION("CPoliciesNode::OnNewPolicy");
  842. HRESULT hr = S_OK;
  843. // do nothing if the server is not even connected
  844. if ( !m_fSdoConnected )
  845. {
  846. return S_OK;
  847. }
  848. CComPtr<IComponent> spComponent;
  849. CComPtr<IComponentData> spComponentData;
  850. CComPtr<IConsole> spConsole;
  851. CComPtr<ISdo> spProfileSdo = NULL;
  852. CComPtr<IDispatch> spPolicyDispatch = NULL;
  853. CComPtr<IDispatch> spProfileDispatch = NULL;
  854. CComPtr<ISdo> spPolicySdo;
  855. CPolicyNode* pPolicyNode = NULL;
  856. CComBSTR bstrName;
  857. // We need to make sure that the result child list as been populated
  858. // initially from the SDO's, before we add anything new to it,
  859. // otherwise we may get an item showing up in our list twice.
  860. // See note for CNodeWithResultChildrenList::AddSingleChildToListAndCauseViewUpdate.
  861. if ( FALSE == m_bResultChildrenListPopulated )
  862. {
  863. hr = PopulateResultChildrenList();
  864. DebugTrace(ERROR_NAPMMC_POLICIESNODE, "PopulateResultChildrenList() returned %x", hr);
  865. if( FAILED(hr) )
  866. {
  867. goto failure;
  868. }
  869. m_bResultChildrenListPopulated = TRUE;
  870. }
  871. // One of them should be NULL and the other non-null.
  872. spComponentData = (IComponentData *)(dynamic_cast<CComponentData*>(pObj));
  873. if( spComponentData == NULL )
  874. {
  875. // It must be a CComponent pointer.
  876. spComponent = (IComponent *) (dynamic_cast<CComponent*>(pObj));
  877. _ASSERTE( spComponent != NULL );
  878. }
  879. // Attempt to get our local copy of IConsole from either our CComponentData or CComponent.
  880. if( spComponentData != NULL )
  881. {
  882. spConsole = ( (CComponentData *) spComponentData.p )->m_spConsole;
  883. }
  884. else
  885. {
  886. // If we don't have pComponentData, we better have pComponent
  887. _ASSERTE( spComponent != NULL );
  888. spConsole = ( (CComponent *) spComponent.p )->m_spConsole;
  889. }
  890. // Create a new policy node.
  891. pPolicyNode = new CPolicyNode(
  892. this,
  893. m_pszServerAddress,
  894. &m_AttrList,
  895. TRUE,
  896. m_fUseDS,
  897. IsWin2kServer() // is a Win2k machine?
  898. );
  899. if( ! pPolicyNode )
  900. {
  901. // We failed to create the policy node.
  902. hr = HRESULT_FROM_WIN32(GetLastError());
  903. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "failed to create a policy node, err = %x", hr);
  904. goto failure;
  905. }
  906. // Try to Add a new policy SDO to the policies sdo collection.
  907. spPolicyDispatch.p = NULL;
  908. TCHAR tzTempName[MAX_PATH+1];
  909. do
  910. {
  911. //
  912. // create a temporary name. we used the seconds elapsed as the temp name
  913. // so the chance of getting identical names is very small
  914. //
  915. time_t ltime;
  916. time(&ltime);
  917. wsprintf(tzTempName, _T("TempName%ld"), ltime);
  918. bstrName.Empty();
  919. bstrName = tzTempName; // temporary policy name
  920. hr = m_spPoliciesCollectionSdo->Add(bstrName, (IDispatch **) &spPolicyDispatch.p );
  921. //
  922. // we keep looping around until the policy can be successfully added.
  923. // We will get E_INVALIDARG when the name already exists
  924. //
  925. } while ( hr == E_INVALIDARG );
  926. if( FAILED( hr ) )
  927. {
  928. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "PoliciesCollection->Add() failed, err = %x", hr);
  929. // We could not create the object.
  930. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_ADDPOLICY, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  931. goto failure;
  932. }
  933. DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "policiesCollection->Add() succeeded");
  934. // Query the returned IDispatch interface for an ISdo interface.
  935. _ASSERTE( spPolicyDispatch.p != NULL );
  936. hr = spPolicyDispatch.p->QueryInterface( IID_ISdo, (void **) &spPolicySdo );
  937. if( ! spPolicySdo )
  938. {
  939. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't get ISdo from the new created IDispatch, err = %x", hr);
  940. // For some reason, we couldn't get the policy sdo.
  941. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_QUERYINTERFACE, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  942. goto failure;
  943. }
  944. // now we create a new profile with the same name
  945. hr = m_spProfilesCollectionSdo->Add(bstrName, &spProfileDispatch);
  946. if ( FAILED(hr) )
  947. {
  948. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "profilesCollection->Add() failed, err = %x", hr);
  949. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_ADDPROFILE, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  950. goto failure;
  951. }
  952. DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "profilesCollection->Add() succeeded");
  953. // Query the returned IDispatch interface for an ISdo interface.
  954. _ASSERTE( spProfileDispatch != NULL );
  955. hr = spProfileDispatch->QueryInterface(IID_ISdo, (void**)&spProfileSdo);
  956. if ( spProfileSdo == NULL )
  957. {
  958. ATLTRACE(_T("CPoliciesNode::NewPolicy\n"));
  959. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_QUERYINTERFACE, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  960. goto failure;
  961. }
  962. //
  963. // add default attributes to the profiles
  964. //
  965. hr = AddDefaultProfileAttrs(spProfileSdo);
  966. if ( FAILED(hr) )
  967. {
  968. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_ADDATTR, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  969. goto failure;
  970. }
  971. // set the SDO pointers for this policy node
  972. pPolicyNode->SetSdo( spPolicySdo
  973. , m_spDictionarySdo
  974. , spProfileSdo
  975. , m_spProfilesCollectionSdo
  976. , m_spPoliciesCollectionSdo
  977. , m_spSdoServiceControl
  978. );
  979. // no display name yet -- use MUST rename this policy
  980. pPolicyNode->m_bstrDisplayName = _T("");
  981. //
  982. // edit the properties of the new added policy
  983. //
  984. DebugTrace(DEBUG_NAPMMC_POLICIESNODE, "Bringing up the property page for this policy node...");
  985. if (m_ResultChildrenList.GetSize())
  986. pPolicyNode->SetMerit(-1); // cause the policy to be added as the first one
  987. // else, default will be 0, insert to end
  988. hr = BringUpPropertySheetForNode(
  989. pPolicyNode
  990. , spComponentData
  991. , spComponent
  992. , spConsole
  993. , TRUE
  994. , pPolicyNode->m_bstrDisplayName
  995. , FALSE
  996. , MMC_PSO_NEWWIZARDTYPE
  997. );
  998. if( S_OK == hr )
  999. {
  1000. // We finished the wizard.
  1001. if (m_ResultChildrenList.GetSize() > 1)
  1002. NormalizeMerit(pPolicyNode);
  1003. }
  1004. else
  1005. {
  1006. // There was some error, or the user hit cancel -- we should remove the client
  1007. // from the SDO's.
  1008. CComPtr<IDispatch> spDispatch;
  1009. hr = pPolicyNode->m_spPolicySdo->QueryInterface( IID_IDispatch, (void **) & spDispatch );
  1010. _ASSERTE( SUCCEEDED( hr ) );
  1011. // Remove this client from the Clients collection.
  1012. hr = m_spPoliciesCollectionSdo->Remove( spDispatch );
  1013. spDispatch.Release();
  1014. hr = pPolicyNode->m_spProfileSdo->QueryInterface( IID_IDispatch, (void **) & spDispatch );
  1015. _ASSERTE( SUCCEEDED( hr ) );
  1016. // Remove this client from the Clients collection.
  1017. hr = m_spProfilesCollectionSdo->Remove( spDispatch );
  1018. // Delete the node
  1019. delete pPolicyNode;
  1020. }
  1021. return hr;
  1022. failure:
  1023. if (pPolicyNode)
  1024. {
  1025. delete pPolicyNode;
  1026. pPolicyNode = NULL;
  1027. //
  1028. // delete the policy sdo and the profile sdo from the sdo collections
  1029. //
  1030. //
  1031. // we don't need to report error here because
  1032. // 1) there's nothing more we can do if Remove() fails
  1033. // 2) there must be another error reporting about Adding policy earlier
  1034. //
  1035. if ( spPolicyDispatch )
  1036. {
  1037. m_spPoliciesCollectionSdo->Remove( spPolicyDispatch );
  1038. }
  1039. if ( spProfileDispatch )
  1040. {
  1041. m_spProfilesCollectionSdo->Remove( spProfileDispatch );
  1042. }
  1043. }
  1044. return hr;
  1045. }
  1046. //////////////////////////////////////////////////////////////////////////////
  1047. /*++
  1048. CPoliciesNode::RemoveChild
  1049. We override our base class's RemoveChild method to insert code that
  1050. removes the child from the Sdo's as well. We then call our base
  1051. class's RemoveChild method to remove the UI object from the list
  1052. of UI children.
  1053. --*/
  1054. //////////////////////////////////////////////////////////////////////////////
  1055. HRESULT CPoliciesNode::RemoveChild( CPolicyNode* pPolicyNode)
  1056. {
  1057. TRACE_FUNCTION("CPoliciesNode::RemoveChild");
  1058. // Check for preconditions:
  1059. _ASSERTE( m_spPoliciesCollectionSdo != NULL );
  1060. _ASSERTE( pPolicyNode != NULL );
  1061. _ASSERTE( pPolicyNode->m_spPolicySdo != NULL );
  1062. HRESULT hr = S_OK;
  1063. // Try to remove the object from the Sdo's
  1064. // Get the IDispatch interface of this policy Sdo.
  1065. CComPtr<IDispatch> spDispatch;
  1066. // remove the policy SDO
  1067. hr = pPolicyNode->m_spPolicySdo->QueryInterface( IID_IDispatch, (void **) & spDispatch );
  1068. _ASSERTE( SUCCEEDED( hr ) );
  1069. // Remove this policy from the policies collection.
  1070. hr = m_spPoliciesCollectionSdo->Remove( spDispatch );
  1071. if( FAILED( hr ) )
  1072. {
  1073. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't remove the policy SDO from the policies collection, err = %x", hr);
  1074. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_REMOVEPOLICY, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  1075. return hr;
  1076. }
  1077. spDispatch->Release();
  1078. spDispatch.p = NULL;
  1079. // remove the profile SDO
  1080. hr = pPolicyNode->m_spProfileSdo->QueryInterface( IID_IDispatch, (void **) & spDispatch );
  1081. _ASSERTE( SUCCEEDED( hr ) );
  1082. // Remove this profile from the profiles collection.
  1083. hr = m_spProfilesCollectionSdo->Remove( spDispatch );
  1084. if( FAILED( hr ) )
  1085. {
  1086. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "Can't remove the profile SDO from the policies collection, err = %x", hr);
  1087. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_REMOVEPROFILE, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  1088. return hr;
  1089. }
  1090. // Tell the service to reload data.
  1091. HRESULT hrTemp = m_spSdoServiceControl->ResetService();
  1092. if( FAILED( hrTemp ) )
  1093. {
  1094. ErrorTrace(ERROR_NAPMMC_POLICIESNODE, "ISdoServiceControl::ResetService() failed, err = %x", hrTemp);
  1095. }
  1096. // Call our base class's method to remove the child from its list.
  1097. // The RemoveChild method takes care of removing this node from the
  1098. // UI's list of nodes under the parent and performing a refresh of all relevant views.
  1099. CNodeWithResultChildrenList<CPoliciesNode, CPolicyNode, CMeritNodeArray<CPolicyNode*>, CComponentData, CComponent >::RemoveChild( pPolicyNode );
  1100. return hr;
  1101. }
  1102. //+---------------------------------------------------------------------------
  1103. //
  1104. // Function: CPoliciesNode::OnPolicyLocation
  1105. //
  1106. // Synopsis: toggle the location of policy: it could be AD or local
  1107. //
  1108. // Arguments:
  1109. //
  1110. // Returns: HRESULT -
  1111. //
  1112. // History: Created Header byao 4/10/98 1:45:12 AM
  1113. //
  1114. //+---------------------------------------------------------------------------
  1115. HRESULT CPoliciesNode::OnPolicyLocation(bool &bHandled, CSnapInObjectRootBase* pObj )
  1116. {
  1117. TRACE_FUNCTION("CPoliciesNode::OnPolicyLocation");
  1118. return S_OK;
  1119. }
  1120. //+---------------------------------------------------------------------------
  1121. //
  1122. // Function: CPoliciesNode::AddProfAttr
  1123. //
  1124. // Synopsis: Add ONE attribute to the profile attribute collection
  1125. //
  1126. // Argument: ISdoCollection* pProfAttrCollectionSdo
  1127. // ATTRIBUTEID AttrId - default Attribute ID
  1128. // VARIANT* pvarValue - Attribute value for this attribute
  1129. //
  1130. // Returns: succeed or not
  1131. //
  1132. // History: Created Header byao 4/15/98 3:59:38 PM
  1133. //
  1134. //+---------------------------------------------------------------------------
  1135. HRESULT CPoliciesNode::AddProfAttr( ISdoCollection* pProfAttrCollectionSdo,
  1136. ATTRIBUTEID AttrId,
  1137. VARIANT* pvarValue
  1138. )
  1139. {
  1140. TRACE_FUNCTION("CPoliciesNode::AddProfAttr");
  1141. HRESULT hr = S_OK;
  1142. CComBSTR bstr;
  1143. CComPtr<IUnknown> spUnknown;
  1144. CComPtr<IEnumVARIANT> spEnumVariant;
  1145. // create default attributes
  1146. CComPtr<IDispatch> spDispatch;
  1147. spDispatch.p = NULL;
  1148. hr = m_spDictionarySdo->CreateAttribute( AttrId,(IDispatch**)&spDispatch.p);
  1149. if ( !SUCCEEDED(hr) )
  1150. {
  1151. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_CREATEATTR, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  1152. return hr;
  1153. }
  1154. _ASSERTE( spDispatch.p != NULL );
  1155. // add this node to profile attribute collection
  1156. hr = pProfAttrCollectionSdo->Add(NULL, (IDispatch**)&spDispatch.p);
  1157. if ( !SUCCEEDED(hr) )
  1158. {
  1159. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_ADDATTR, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  1160. return hr;
  1161. }
  1162. //
  1163. // get the ISdo pointer for this attribute
  1164. //
  1165. CComPtr<ISdo> spAttrSdo;
  1166. hr = spDispatch->QueryInterface( IID_ISdo, (void **) &spAttrSdo);
  1167. if ( !SUCCEEDED(hr) )
  1168. {
  1169. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_QUERYINTERFACE, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  1170. return hr;
  1171. }
  1172. _ASSERTE( spAttrSdo != NULL );
  1173. // set sdo property for this attribute
  1174. hr = spAttrSdo->PutProperty(PROPERTY_ATTRIBUTE_VALUE, pvarValue);
  1175. if ( !SUCCEEDED(hr) )
  1176. {
  1177. ShowErrorDialog( NULL, IDS_ERROR_SDO_ERROR_PUTPROP_ATTR, NULL, hr, USE_DEFAULT, GetComponentData()->m_spConsole );
  1178. return hr;
  1179. }
  1180. return hr;
  1181. }
  1182. //+---------------------------------------------------------------------------
  1183. //
  1184. // Function: CPoliciesNode::AddDefaultAttrs
  1185. //
  1186. // Synopsis: Add some default attributes to the newly created profile
  1187. //
  1188. // Argument: ISdo* pProfileSdo - Sdo pointer to the profile
  1189. //
  1190. // Returns: HRESULT return code
  1191. //
  1192. // History: Created Header byao 4/15/98 3:59:38 PM
  1193. //
  1194. //+---------------------------------------------------------------------------
  1195. HRESULT CPoliciesNode::AddDefaultProfileAttrs(ISdo* pProfileSdo, DWORD dwFlagExclude )
  1196. {
  1197. TRACE_FUNCTION("CPoliciesNode::AddDefaultAttr");
  1198. HRESULT hr = S_OK;
  1199. CComVariant varValue;
  1200. ATTRIBUTEID AttrId;
  1201. //
  1202. // get the attribute collection of this profile
  1203. //
  1204. CComPtr<ISdoCollection> spProfAttrCollectionSdo;
  1205. hr = ::GetSdoInterfaceProperty(pProfileSdo,
  1206. (LONG)PROPERTY_PROFILE_ATTRIBUTES_COLLECTION,
  1207. IID_ISdoCollection,
  1208. (void **) &spProfAttrCollectionSdo
  1209. );
  1210. if ( FAILED(hr) )
  1211. {
  1212. return hr;
  1213. }
  1214. _ASSERTE(spProfAttrCollectionSdo);
  1215. //
  1216. // Default Attribute: ServiceType=Framed, Enumerator
  1217. //
  1218. AttrId = RADIUS_ATTRIBUTE_SERVICE_TYPE;
  1219. // Set value
  1220. V_VT(&varValue) = VT_I4;
  1221. V_I4(&varValue) = 2; // framed
  1222. hr = AddProfAttr(spProfAttrCollectionSdo, AttrId, &varValue);
  1223. if ( !SUCCEEDED(hr) )
  1224. {
  1225. return hr;
  1226. }
  1227. // turn it on again: bug : 337330
  1228. // #if 0 // not to have this default attribute; bug : 241350
  1229. //
  1230. // Default Attribute: FrameProtocol=PPP, Enumerator
  1231. //
  1232. AttrId = RADIUS_ATTRIBUTE_FRAMED_PROTOCOL;
  1233. varValue.Clear();
  1234. V_VT(&varValue) = VT_I4;
  1235. V_I4(&varValue) = 1; // PPP
  1236. hr = AddProfAttr(spProfAttrCollectionSdo, AttrId, &varValue);
  1237. if ( !SUCCEEDED(hr) )
  1238. {
  1239. return hr;
  1240. }
  1241. // #endif // not to have this default attribute; bug : 241350
  1242. // turn it on again: bug : 337330
  1243. //
  1244. // Default Attribute: AuthenticationType=MS-CHAPv2, MS-CHAP, Enumerator,multivalued
  1245. //
  1246. if ((EXCLUDE_AUTH_TYPE & dwFlagExclude) == 0)
  1247. {
  1248. AttrId = IAS_ATTRIBUTE_NP_AUTHENTICATION_TYPE;
  1249. CSafeArray<CComVariant, VT_VARIANT> Values = Dim(4); // 4 values
  1250. Values.Lock();
  1251. varValue.Clear();
  1252. V_VT(&varValue) = VT_I4;
  1253. V_I4(&varValue) = IAS_AUTH_MSCHAP2; // MS-CHAPv2
  1254. Values[0] = varValue;
  1255. varValue.Clear();
  1256. V_VT(&varValue) = VT_I4;
  1257. V_I4(&varValue) = IAS_AUTH_MSCHAP; // MS-CHAP
  1258. Values[1] = varValue;
  1259. varValue.Clear();
  1260. V_VT(&varValue) = VT_I4;
  1261. V_I4(&varValue) = IAS_AUTH_MSCHAP2_CPW; // MS-CHAPv2 Password
  1262. Values[2] = varValue;
  1263. varValue.Clear();
  1264. V_VT(&varValue) = VT_I4;
  1265. V_I4(&varValue) = IAS_AUTH_MSCHAP_CPW; // MS-CHAP Password
  1266. Values[3] = varValue;
  1267. Values.Unlock();
  1268. // We need to use a VARIANT and not a CComVariant here because when
  1269. // CSafeArray's destructor gets called, it will destroy the array
  1270. // -- we don't want CComVariant's destructor to do this as well.
  1271. // Ideally, we'd like to use a CComVariant, but once we move Values
  1272. // into a CComVariant, we should "Detach" the memory from
  1273. // CSafeArray so that it no longer controls destruction,
  1274. // but Baogang's CSafeArray class doesn't have a Detach method.
  1275. // ISSUE: Figure out why CSafeArray is causing a problem here
  1276. // but not elsewhere -- this CSafeArray class is largely
  1277. // untested and has been problematic in the past,
  1278. // so we should consider replacing it.
  1279. VARIANT varArray;
  1280. VariantInit( &varArray );
  1281. SAFEARRAY sa = (SAFEARRAY)Values;
  1282. V_VT(&varArray) = VT_ARRAY | VT_VARIANT;
  1283. V_ARRAY(&varArray) = &sa;
  1284. hr = AddProfAttr(spProfAttrCollectionSdo, AttrId, &varArray);
  1285. }
  1286. return hr;
  1287. }
  1288. //+---------------------------------------------------------------------------
  1289. //
  1290. // Function: CPoliciesNode::CheckActivePropertyPages
  1291. //
  1292. // Synopsis: Check whether any policy property page is up.
  1293. //
  1294. // Returns: BOOL TRUE: yes, there's at least one property page up
  1295. // FALSE no, no property page is found
  1296. //
  1297. // History: Created Header byao 4/16/98 3:59:38 PM
  1298. //
  1299. //+---------------------------------------------------------------------------
  1300. BOOL CPoliciesNode::CheckActivePropertyPages ()
  1301. {
  1302. //
  1303. // check whether ANY policy node has a property page up
  1304. //
  1305. for (int iIndex=0; iIndex<m_ResultChildrenList.GetSize(); iIndex++)
  1306. {
  1307. if ( m_ResultChildrenList[iIndex]->m_pPolicyPage1 )
  1308. {
  1309. // We found a property sheet already up for this node.
  1310. return TRUE;
  1311. }
  1312. } // for
  1313. return FALSE;
  1314. }
  1315. //+---------------------------------------------------------------------------
  1316. //
  1317. // Function: CPoliciesNode::ReloadPoliciesFromNewLocation
  1318. //
  1319. // Synopsis: Reload policies from another location (DS or Local)
  1320. //
  1321. // Returns: HRESULT hr : return code
  1322. //
  1323. // History: Created Header byao 4/16/98 3:59:38 PM
  1324. //
  1325. //+---------------------------------------------------------------------------
  1326. HRESULT CPoliciesNode::ReloadPoliciesFromNewLocation( )
  1327. {
  1328. TRACE_FUNCTION("CPoliciesNode::ReloadPoliciesFromNewLocation");
  1329. return S_OK;
  1330. }
  1331. //+---------------------------------------------------------------------------
  1332. //
  1333. // Function: CPoliciesNode::FindChildWithName
  1334. //
  1335. // Synopsis: try to find a child with the same name
  1336. //
  1337. // Arguments: LPTSTR pszName - name of the child to look for
  1338. //
  1339. // Returns: CPolicyNode* pChild -- pointer to the child with the same name
  1340. // NULL -- not found
  1341. //
  1342. // History: Created Header byao 4/30/98 4:46:05 PM
  1343. //
  1344. //+---------------------------------------------------------------------------
  1345. CPolicyNode* CPoliciesNode::FindChildWithName(LPCTSTR pszName)
  1346. {
  1347. TRACE_FUNCTION("CPoliciesNode::FindChildWithName");
  1348. int nSize = m_ResultChildrenList.GetSize();
  1349. for (int iIndex=0; iIndex<nSize; iIndex++)
  1350. {
  1351. if ( _tcsicmp(m_ResultChildrenList[iIndex]->m_bstrDisplayName, pszName) == 0 )
  1352. {
  1353. return (CPolicyNode*) m_ResultChildrenList[iIndex];
  1354. }
  1355. }
  1356. return NULL;
  1357. }
  1358. //+---------------------------------------------------------------------------
  1359. //
  1360. // Function: CPoliciesNode::GetChildrenCount
  1361. //
  1362. // Synopsis: how many children do you have?
  1363. //
  1364. // Arguments: None
  1365. //
  1366. // Returns: int -
  1367. //
  1368. // History: Created Header byao 6/2/98 6:10:43 PM
  1369. //
  1370. //+---------------------------------------------------------------------------
  1371. int CPoliciesNode::GetChildrenCount()
  1372. {
  1373. TRACE_FUNCTION("CPoliciesNode::GetChildrenCount");
  1374. return m_ResultChildrenList.GetSize();
  1375. }
  1376. //////////////////////////////////////////////////////////////////////////////
  1377. /*++
  1378. CPoliciesNode::SetName
  1379. --*/
  1380. //////////////////////////////////////////////////////////////////////////////
  1381. HRESULT CPoliciesNode::SetName( BOOL bPoliciesFromDirectoryService, LPWSTR szPolicyLocation, IConsole * pConsole )
  1382. {
  1383. WCHAR lpszTemp[NAP_MAX_STRING];
  1384. int nLoadStringResult;
  1385. HRESULT hr = S_OK;
  1386. // Get the base name for the policies node.
  1387. lpszTemp[0] = NULL;
  1388. nLoadStringResult = LoadString( _Module.GetResourceInstance(),
  1389. IDS_POLICIES_NODE,
  1390. lpszTemp,
  1391. NAP_MAX_STRING
  1392. );
  1393. _ASSERT( nLoadStringResult > 0 );
  1394. // Put the base name into our display string.
  1395. m_bstrDisplayName = lpszTemp;
  1396. if( pConsole )
  1397. {
  1398. // We were passed an IConsole pointer.
  1399. // We should use it to update the MMC scope pane display for this node.
  1400. CComQIPtr< IConsoleNameSpace, &IID_IConsoleNameSpace > spConsoleNameSpace( pConsole );
  1401. if( ! spConsoleNameSpace )
  1402. {
  1403. return E_FAIL;
  1404. }
  1405. hr = spConsoleNameSpace->SetItem( & m_scopeDataItem );
  1406. }
  1407. return hr;
  1408. }
  1409. //////////////////////////////////////////////////////////////////////////////
  1410. /*++
  1411. CPoliciesNode::FillData
  1412. The server node need to override CSnapInItem's implementation of this so that
  1413. we can
  1414. also support a clipformat for exchanging machine names with any snapins
  1415. extending us.
  1416. --*/
  1417. //////////////////////////////////////////////////////////////////////////////
  1418. STDMETHODIMP CPoliciesNode::FillData(CLIPFORMAT cf, LPSTREAM pStream)
  1419. {
  1420. ATLTRACE(_T("# CClientsNode::FillData\n"));
  1421. // Check for preconditions:
  1422. // None.
  1423. HRESULT hr = DV_E_CLIPFORMAT;
  1424. ULONG uWritten = 0;
  1425. if (cf == CF_MMC_NodeID)
  1426. {
  1427. ::CString SZNodeID = (LPCTSTR)GetSZNodeType();
  1428. if (m_fExtendingIAS)
  1429. {
  1430. SZNodeID += L":Ext_IAS:";
  1431. }
  1432. SZNodeID += m_pszServerAddress;
  1433. DWORD dwIdSize = 0;
  1434. SNodeID2* NodeId = NULL;
  1435. BYTE *id = NULL;
  1436. DWORD textSize = (SZNodeID.GetLength()+ 1) * sizeof(TCHAR);
  1437. dwIdSize = textSize + sizeof(SNodeID2);
  1438. try
  1439. {
  1440. NodeId = (SNodeID2 *)_alloca(dwIdSize);
  1441. }
  1442. catch(...)
  1443. {
  1444. return E_OUTOFMEMORY;
  1445. }
  1446. NodeId->dwFlags = 0;
  1447. NodeId->cBytes = textSize;
  1448. memcpy(NodeId->id,(BYTE*)(LPCTSTR)SZNodeID, textSize);
  1449. return pStream->Write(NodeId, dwIdSize, &uWritten);
  1450. }
  1451. // Call the method which we're overriding to let it handle the
  1452. // rest of the possible cases as usual.
  1453. return CNodeWithResultChildrenList< CPoliciesNode, CPolicyNode, CMeritNodeArray<CPolicyNode*>, CComponentData, CComponent >::FillData( cf, pStream );
  1454. }
  1455. //////////////////////////////////////////////////////////////////////////////
  1456. // CPoliciesNode::IsWin2kServer
  1457. //////////////////////////////////////////////////////////////////////////////
  1458. bool CPoliciesNode::IsWin2kServer() throw ()
  1459. {
  1460. if (m_serverType == unknown)
  1461. {
  1462. HRESULT hr = GetServerType();
  1463. ASSERT(SUCCEEDED(hr));
  1464. }
  1465. return m_serverType == win2k;
  1466. }
  1467. //////////////////////////////////////////////////////////////////////////////
  1468. // CPoliciesNode::GetServerType
  1469. //////////////////////////////////////////////////////////////////////////////
  1470. HRESULT CPoliciesNode::GetServerType()
  1471. {
  1472. const WCHAR KEY[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion";
  1473. const WCHAR VALUE[] = L"CurrentBuildNumber";
  1474. const unsigned int WIN2K_BUILD = 2195;
  1475. LONG error;
  1476. HKEY hklm = HKEY_LOCAL_MACHINE;
  1477. // Only do a remote connect when machineName is specified.
  1478. CRegKey remote;
  1479. if (m_pszServerAddress && m_pszServerAddress[0])
  1480. {
  1481. error = RegConnectRegistryW(
  1482. m_pszServerAddress,
  1483. HKEY_LOCAL_MACHINE,
  1484. &remote.m_hKey
  1485. );
  1486. if (error) { return error; }
  1487. hklm = remote;
  1488. }
  1489. CRegKey currentVersion;
  1490. error = currentVersion.Open(hklm, KEY, KEY_READ);
  1491. if (error) { return error; }
  1492. WCHAR data[16];
  1493. DWORD dataLen = sizeof(data);
  1494. error = currentVersion.QueryValue(data, VALUE, &dataLen);
  1495. if (error) { return error; }
  1496. unsigned int buildNum = _wtol(data);
  1497. if(buildNum < WIN2K_BUILD)
  1498. {
  1499. m_serverType = nt4;
  1500. }
  1501. else if (buildNum == WIN2K_BUILD)
  1502. {
  1503. m_serverType = win2k;
  1504. }
  1505. else
  1506. {
  1507. m_serverType = win5_1_or_later;
  1508. }
  1509. return S_OK;
  1510. }