Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1802 lines
57 KiB

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