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.

1119 lines
28 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. /*++
  3. Copyright (C) Microsoft Corporation, 1997 - 1999
  4. Module Name:
  5. MachineNode.cpp
  6. Abstract:
  7. Implementation file for the CMachineNode class.
  8. Revision History:
  9. mmaguire 12/03/97
  10. byao 6/11/98 Added asynchrnous connect
  11. --*/
  12. //////////////////////////////////////////////////////////////////////////////
  13. //////////////////////////////////////////////////////////////////////////////
  14. // BEGIN INCLUDES
  15. //
  16. // standard includes:
  17. //
  18. #include "Precompiled.h"
  19. //
  20. // where we can find declaration for main class in this file:
  21. //
  22. #include "MachineNode.h"
  23. #include "Component.h"
  24. #include "SnapinNode.cpp" // Template implementation
  25. //
  26. // where we can find declarations needed in this file:
  27. //
  28. #include "NapUtil.h"
  29. #include "MachineEnumTask.h"
  30. #include "NodeTypeGUIDS.h"
  31. #include "ChangeNotification.h"
  32. //
  33. // END INCLUDES
  34. //////////////////////////////////////////////////////////////////////////////
  35. //////////////////////////////////////////////////////////////////////////////
  36. /*++
  37. CMachineNode::IsSupportedGUID
  38. Used to determine whether we extend the node type of a given GUID, and sets
  39. the m_enumExtendedSnapin variable to indicate what snapin we are extending.
  40. --*/
  41. //////////////////////////////////////////////////////////////////////////////
  42. BOOL CMachineNode::IsSupportedGUID( GUID & guid )
  43. {
  44. if( IsEqualGUID( guid, InternetAuthenticationServiceGUID_ROOTNODETYPE ) )
  45. {
  46. m_enumExtendedSnapin = INTERNET_AUTHENTICATION_SERVICE_SNAPIN;
  47. return TRUE;
  48. }
  49. else
  50. {
  51. if( IsEqualGUID( guid, NetworkConsoleGUID_ROOTNODETYPE) )
  52. {
  53. m_enumExtendedSnapin = NETWORK_MANAGEMENT_SNAPIN;
  54. return TRUE;
  55. }
  56. else
  57. {
  58. if( IsEqualGUID( guid, RoutingAndRemoteAccessGUID_MACHINENODETYPE ) )
  59. {
  60. m_enumExtendedSnapin = RRAS_SNAPIN;
  61. return TRUE;
  62. }
  63. }
  64. }
  65. return FALSE;
  66. }
  67. //////////////////////////////////////////////////////////////////////////////
  68. /*++
  69. CMachineNode::GetExtNodeObject
  70. Depending on which snapin we are extending, when queried for a node object
  71. corresponding to a particular machine, we must decide which node we want
  72. to give a pointer to.
  73. When we extend a snapin like IAS or Network Management, where there is one
  74. instance of a snapin per machine being configured, we simply return a pointer
  75. to "this" -- this CMachineNode object is the single one being administed.
  76. When we extend a snapin like RRAS where there is an "Enterprise" view and
  77. one snapin may need to manage a view of multiple machines, this CMachineNode
  78. will act as a redirector to a CMachineNode in a list of m_mapMachineNodes it
  79. maintains which corresponds to the appropriate machines.
  80. --*/
  81. //////////////////////////////////////////////////////////////////////////////
  82. CSnapInItem * CMachineNode::GetExtNodeObject(LPDATAOBJECT pDataObject, CMachineNode * pDataClass )
  83. {
  84. TRACE_FUNCTION("CMachineNode::GetExtNodeObject");
  85. if( m_enumExtendedSnapin == INTERNET_AUTHENTICATION_SERVICE_SNAPIN
  86. || m_enumExtendedSnapin == NETWORK_MANAGEMENT_SNAPIN )
  87. {
  88. // There is one instance of a machine node per snapin.
  89. // This machine node is a "virtual root" that shadows the node being extended.
  90. m_fNodeHasUI = TRUE;
  91. return this;
  92. }
  93. else
  94. {
  95. try
  96. {
  97. _ASSERTE( m_enumExtendedSnapin == RRAS_SNAPIN );
  98. // There are many machine nodes and one extension snapin needs to handle them all.
  99. // We use this function to extract the machine name from the clipboard format.
  100. // It will set the corrent value in m_bstrServerAddress.
  101. m_fAlreadyAnalyzedDataClass = FALSE;
  102. InitDataClass( pDataObject, pDataClass );
  103. // See if we already have a CMachineNode object corresponding to the
  104. // machine named in m_bstrServerAddress and insert it if we do not.
  105. SERVERSMAP::iterator theIterator;
  106. BOOL bAddedAsLocal = ExtractComputerAddedAsLocal(pDataObject);
  107. std::basic_string< wchar_t > MyString = m_bstrServerAddress;
  108. // local machine has special entry
  109. if(bAddedAsLocal)
  110. MyString = _T("");
  111. CMachineNode * pMachineNode = NULL;
  112. theIterator = m_mapMachineNodes.find(MyString);
  113. if( theIterator == m_mapMachineNodes.end() )
  114. {
  115. // We need to insert a new CMachineNode object for m_bstrServerAddress.
  116. pMachineNode = new CMachineNode();
  117. pMachineNode->m_pComponentData = m_pComponentData;
  118. pMachineNode->m_enumExtendedSnapin = m_enumExtendedSnapin;
  119. m_mapMachineNodes.insert( SERVERSMAP::value_type( MyString, pMachineNode ) );
  120. // ISSUE: We should be able to use the pair returned from insert above,
  121. // but for now, just use find again.
  122. theIterator = m_mapMachineNodes.find(MyString);
  123. }
  124. else
  125. pMachineNode = (CMachineNode*)theIterator->second;
  126. // RRAS refresh advise setup F bug 213623:
  127. if(!pMachineNode->m_spRtrAdviseSink)
  128. pMachineNode->m_spRtrAdviseSink.p = CRtrAdviseSinkForIAS<CMachineNode>::SetAdvise(pMachineNode, pDataObject);
  129. pMachineNode->m_fNodeHasUI = TRUE;
  130. // ~RRAS
  131. // We already have a CMachineNode for this object.
  132. return theIterator->second;
  133. }
  134. catch(...)
  135. {
  136. // Error.
  137. return NULL;
  138. }
  139. }
  140. }
  141. //////////////////////////////////////////////////////////////////////////////
  142. /*++
  143. CMachineNode::OnRRASChange
  144. // OnRRASChange -- to decide if to show RAP node under the machine node
  145. // Only show RAP node if NT Authentication is selected
  146. --*/
  147. HRESULT CMachineNode::OnRRASChange(
  148. /* [in] */ LONG_PTR ulConnection,
  149. /* [in] */ DWORD dwChangeType,
  150. /* [in] */ DWORD dwObjectType,
  151. /* [in] */ LPARAM lUserParam,
  152. /* [in] */ LPARAM lParam)
  153. {
  154. HRESULT hr = S_OK;
  155. if(m_fNodeHasUI)
  156. hr = TryShow(NULL);
  157. return S_OK;
  158. }
  159. //==============
  160. //==============
  161. HRESULT CMachineNode::TryShow(BOOL* pbVisible )
  162. {
  163. HRESULT hr = S_OK;
  164. CComPtr<IConsole> spConsole;
  165. CComPtr<IConsoleNameSpace> spConsoleNameSpace;
  166. BOOL bShow = FALSE;
  167. if(!m_bServerSupported || !m_fAlreadyAnalyzedDataClass || !m_pPoliciesNode || !m_fNodeHasUI)
  168. return hr;
  169. // when RRAS_SNAPIN extension
  170. if(m_enumExtendedSnapin == RRAS_SNAPIN)
  171. {
  172. BSTR bstrMachine = NULL;
  173. if(!m_bConfigureLocal)
  174. bstrMachine = m_bstrServerAddress;
  175. bShow = (IsRRASConfigured(bstrMachine) && IsRRASUsingNTAuthentication(bstrMachine));
  176. }
  177. // IAS, show only IAS service is installed on the machine
  178. else if (INTERNET_AUTHENTICATION_SERVICE_SNAPIN == m_enumExtendedSnapin)
  179. {
  180. hr = IfServiceInstalled(m_bstrServerAddress, _T("IAS"), &bShow);
  181. if(hr != S_OK) return hr;
  182. }
  183. else // always show
  184. {
  185. bShow = TRUE;
  186. }
  187. // deal with the node
  188. hr = m_pComponentData->m_spConsole->QueryInterface(
  189. IID_IConsoleNameSpace,
  190. (VOID**)(&spConsoleNameSpace) );
  191. if(S_OK != hr)
  192. goto Error;
  193. if ( bShow && m_pPoliciesNode->m_scopeDataItem.ID == NULL) // show the node
  194. {
  195. hr = spConsoleNameSpace->InsertItem( &(m_pPoliciesNode->m_scopeDataItem) );
  196. // _ASSERT( NULL != m_pPoliciesNode->m_scopeDataItem.ID );
  197. }
  198. else if (!bShow && m_pPoliciesNode->m_scopeDataItem.ID != NULL) // hide
  199. { // hide the node
  200. hr = spConsoleNameSpace->DeleteItem( m_pPoliciesNode->m_scopeDataItem.ID, TRUE );
  201. m_pPoliciesNode->m_scopeDataItem.ID = NULL;
  202. }
  203. if(hr == S_OK && pbVisible)
  204. *pbVisible = bShow;
  205. Error:
  206. return hr;
  207. }
  208. //////////////////////////////////////////////////////////////////////////////
  209. /*++
  210. CMachineNode::CMachineNode
  211. Constructor
  212. --*/
  213. //////////////////////////////////////////////////////////////////////////////
  214. CMachineNode::CMachineNode(): CSnapinNode<CMachineNode, CComponentData, CComponent>( NULL )
  215. {
  216. TRACE_FUNCTION("CMachineNode::CMachineNode");
  217. // The children subnodes have not yet been created.
  218. m_pPoliciesNode = NULL;
  219. // Set the display name for this object
  220. m_bstrDisplayName = L"@Some Machine";
  221. // In IComponentData::Initialize, we are asked to inform MMC of
  222. // the icons we would like to use for the scope pane.
  223. // Here we store an index to which of these images we
  224. // want to be used to display this node
  225. m_scopeDataItem.nImage = IDBI_NODE_MACHINE_CLOSED;
  226. m_scopeDataItem.nOpenImage = IDBI_NODE_MACHINE_OPEN;
  227. //
  228. // initialize all the SDO pointers
  229. //
  230. m_fAlreadyAnalyzedDataClass = FALSE;
  231. // connected?
  232. m_fSdoConnected = FALSE;
  233. // default to not configuring the local machine
  234. m_bConfigureLocal = FALSE;
  235. m_fUseActiveDirectory = FALSE;
  236. m_fDSAvailable = FALSE;
  237. // helper class that connect to server asynchrnously
  238. m_pConnectionToServer = NULL;
  239. m_fNodeHasUI = FALSE;
  240. m_bServerSupported = TRUE;
  241. m_enumExtendedSnapin = INTERNET_AUTHENTICATION_SERVICE_SNAPIN;
  242. }
  243. //////////////////////////////////////////////////////////////////////////////
  244. /*++
  245. CMachineNode::~CMachineNode
  246. Destructor
  247. --*/
  248. //////////////////////////////////////////////////////////////////////////////
  249. CMachineNode::~CMachineNode()
  250. {
  251. TRACE_FUNCTION("CMachineNode::~CMachineNode");
  252. // RRAS refresh
  253. if(m_spRtrAdviseSink != NULL)
  254. {
  255. m_spRtrAdviseSink->ReleaseSink();
  256. m_spRtrAdviseSink.Release();
  257. }
  258. // ~RRAS
  259. if( NULL != m_pConnectionToServer )
  260. {
  261. m_pConnectionToServer->Release(TRUE);
  262. }
  263. // Delete children nodes
  264. delete m_pPoliciesNode;
  265. // Delete the list of machines in case we are extending a snapin with
  266. // enterprise view like RRAS.
  267. SERVERSMAP::iterator theIterator;
  268. for( theIterator = m_mapMachineNodes.begin(); theIterator != m_mapMachineNodes.end(); ++theIterator )
  269. {
  270. delete theIterator->second;
  271. }
  272. m_mapMachineNodes.clear();
  273. }
  274. //////////////////////////////////////////////////////////////////////////////
  275. /*++
  276. CMachineNode::GetResultPaneColInfo
  277. See CSnapinNode::GetResultPaneColInfo (which this method overrides) for detailed info.
  278. --*/
  279. //////////////////////////////////////////////////////////////////////////////
  280. LPOLESTR CMachineNode::GetResultPaneColInfo(int nCol)
  281. {
  282. TRACE_FUNCTION("CMachineNode::GetResultPaneColInfo");
  283. if (nCol == 0)
  284. {
  285. return m_bstrDisplayName;
  286. }
  287. // TODO : Return the text for other columns
  288. return OLESTR("Running");
  289. }
  290. HRESULT CMachineNode::OnRemoveChildren(
  291. LPARAM arg
  292. , LPARAM param
  293. , IComponentData * pComponentData
  294. , IComponent * pComponent
  295. , DATA_OBJECT_TYPES type
  296. )
  297. {
  298. // policy node will be removed, so we should set the ID to 0
  299. if(m_pPoliciesNode)
  300. m_pPoliciesNode->m_scopeDataItem.ID = 0;
  301. // disconnect RRAS on change notify
  302. // RRAS refresh
  303. if(m_spRtrAdviseSink != NULL)
  304. {
  305. m_spRtrAdviseSink->ReleaseSink();
  306. m_spRtrAdviseSink.Release();
  307. }
  308. m_fNodeHasUI = FALSE;
  309. return S_OK;
  310. }
  311. //////////////////////////////////////////////////////////////////////////////
  312. /*++
  313. CMachineNode::DataRefresh
  314. --*/
  315. //////////////////////////////////////////////////////////////////////////////
  316. // called to refresh the nodes
  317. HRESULT CMachineNode::DataRefresh()
  318. {
  319. HRESULT hr = S_OK;
  320. CComPtr<ISdo> spSdo;
  321. CComPtr<ISdoDictionaryOld> spDic;
  322. hr = m_pConnectionToServer->ReloadSdo(&spSdo, &spDic);
  323. // refresh client node
  324. if(hr == S_OK)
  325. {
  326. hr = m_pPoliciesNode->DataRefresh(spSdo, spDic);
  327. }
  328. return hr;
  329. }
  330. //////////////////////////////////////////////////////////////////////////////
  331. /*++
  332. CMachineNode::OnExpand
  333. See CSnapinNode::OnExpand (which this method overrides) for detailed info.
  334. --*/
  335. //////////////////////////////////////////////////////////////////////////////
  336. HRESULT CMachineNode::OnExpand(
  337. LPARAM arg
  338. , LPARAM param
  339. , IComponentData * pComponentData
  340. , IComponent * pComponent
  341. , DATA_OBJECT_TYPES type
  342. )
  343. {
  344. TRACE_FUNCTION("CMachineNode::OnExpand");
  345. IConsoleNameSpace * pConsoleNameSpace;
  346. HRESULT hr = S_FALSE;
  347. if( TRUE == arg )
  348. {
  349. // we are expanding the root node -- which is the machine node here.
  350. // Try to create the children of this Machine node
  351. if( NULL == m_pPoliciesNode )
  352. {
  353. m_pPoliciesNode = new CPoliciesNode
  354. (
  355. this,
  356. m_bstrServerAddress,
  357. m_enumExtendedSnapin == INTERNET_AUTHENTICATION_SERVICE_SNAPIN
  358. );
  359. }
  360. if( NULL == m_pPoliciesNode )
  361. {
  362. hr = E_OUTOFMEMORY;
  363. // Use MessageBox() rather than IConsole::MessageBox() here because the
  364. // first time this gets called m_ipConsole is not fully initialized
  365. // ISSUE: The above statement is probably not true for this node.
  366. ::MessageBox( NULL, L"@Unable to allocate new nodes", L"CMachineNode::OnExpand", MB_OK );
  367. return(hr);
  368. }
  369. //
  370. // we need to get all the SDO pointers, this include the SdoServer,
  371. // Dictionary, Profile collection, policy collection and condition collection
  372. //
  373. //todo: report error when not connected?
  374. hr = BeginConnectAction();
  375. if ( FAILED(hr) )
  376. {
  377. return hr;
  378. }
  379. // But to get that, first we need IConsole
  380. CComPtr<IConsole> spConsole;
  381. if( pComponentData != NULL )
  382. {
  383. spConsole = ((CComponentData*)pComponentData)->m_spConsole;
  384. }
  385. else
  386. {
  387. // We should have a non-null pComponent
  388. spConsole = ((CComponent*)pComponent)->m_spConsole;
  389. }
  390. _ASSERTE( spConsole != NULL );
  391. hr = spConsole->QueryInterface(IID_IConsoleNameSpace, (VOID**)(&pConsoleNameSpace) );
  392. _ASSERT( S_OK == hr );
  393. // This was done in MeanGene's Step 3 -- I'm guessing MMC wants this filled in
  394. m_pPoliciesNode->m_scopeDataItem.relativeID = (HSCOPEITEM) param;
  395. #ifndef ALWAYS_SHOW_RAP_NODE
  396. hr = TryShow(NULL);
  397. #else
  398. hr = pConsoleNameSpace->InsertItem( &(m_pPoliciesNode->m_scopeDataItem) );
  399. _ASSERT( NULL != m_pPoliciesNode->m_scopeDataItem.ID );
  400. #endif
  401. pConsoleNameSpace->Release(); // Don't forget to do this!
  402. }
  403. else // arg != TRUE so not expanding
  404. {
  405. // do nothing for now -- I don't think arg = FALSE is even implemented
  406. // for MMC v. 1.0 or 1.1
  407. }
  408. return hr;
  409. }
  410. //////////////////////////////////////////////////////////////////////////////
  411. /*++
  412. CMachineNode::OnRename
  413. See CSnapinNode::OnRename (which this method overrides) for detailed info.
  414. --*/
  415. //////////////////////////////////////////////////////////////////////////////
  416. HRESULT CMachineNode::OnRename(
  417. LPARAM arg
  418. , LPARAM param
  419. , IComponentData * pComponentData
  420. , IComponent * pComponent
  421. , DATA_OBJECT_TYPES type
  422. )
  423. {
  424. TRACE_FUNCTION("MachineNode::OnRename");
  425. HRESULT hr = S_FALSE;
  426. //ISSUE: Consider moving this into base CNAPNode class or a CLeafNode class
  427. OLECHAR * pTemp = new OLECHAR[lstrlen((OLECHAR*) param) + 1];
  428. if ( NULL == pTemp )
  429. {
  430. return S_FALSE;
  431. }
  432. lstrcpy( pTemp, (OLECHAR*) param );
  433. m_bstrDisplayName = pTemp;
  434. return S_OK;
  435. }
  436. //////////////////////////////////////////////////////////////////////////////
  437. /*++
  438. CMachineNode::SetVerbs
  439. See CSnapinNode::SetVerbs (which this method overrides) for detailed info.
  440. --*/
  441. //////////////////////////////////////////////////////////////////////////////
  442. HRESULT CMachineNode::SetVerbs( IConsoleVerb * pConsoleVerb )
  443. {
  444. TRACE_FUNCTION("CMachineNode::SetVerbs");
  445. HRESULT hr = S_OK;
  446. // We want the user to be able to choose Properties on this node
  447. hr = pConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE );
  448. // We want the default verb to be Properties
  449. hr = pConsoleVerb->SetDefaultVerb( MMC_VERB_PROPERTIES );
  450. // We want the user to be able to delete this node
  451. hr = pConsoleVerb->SetVerbState( MMC_VERB_DELETE, ENABLED, TRUE );
  452. // We want the user to be able to rename this node
  453. hr = pConsoleVerb->SetVerbState( MMC_VERB_RENAME, ENABLED, TRUE );
  454. return hr;
  455. }
  456. //////////////////////////////////////////////////////////////////////////////
  457. /*++
  458. CMachineNode::GetComponentData
  459. This method returns our unique CComponentData object representing the scope
  460. pane of this snapin.
  461. It relies upon the fact that each node has a pointer to its parent,
  462. except for the root node, which instead has a member variable pointing
  463. to CComponentData.
  464. This would be a useful function to use if, for example, you need a reference
  465. to some IConsole but you weren't passed one. You can use GetComponentData
  466. and then use the IConsole pointer which is a member variable of our
  467. CComponentData object.
  468. --*/
  469. //////////////////////////////////////////////////////////////////////////////
  470. CComponentData * CMachineNode::GetComponentData( void )
  471. {
  472. TRACE_FUNCTION("CMachineNode::GetComponentData");
  473. return m_pComponentData;
  474. return NULL;
  475. }
  476. //+---------------------------------------------------------------------------
  477. //
  478. // Function: CMachineNode::InitClipboardFormat
  479. //
  480. // Synopsis: initialize the clipboard format that's used to pass computer name
  481. // from the primary snap-in and extension snap-in
  482. //
  483. // Arguments: None
  484. //
  485. // Returns: Nothing
  486. //
  487. // History: Created Header byao 2/25/98 7:04:33 PM
  488. //
  489. //+---------------------------------------------------------------------------
  490. void CMachineNode::InitClipboardFormat()
  491. {
  492. TRACE_FUNCTION("CMachineNode::InitClipboardFormat");
  493. // Init a clipboard format which will allow us to exchange
  494. // machine name information.
  495. m_CCF_MMC_SNAPIN_MACHINE_NAME = (CLIPFORMAT) RegisterClipboardFormat(_T("MMC_SNAPIN_MACHINE_NAME"));
  496. }
  497. //+---------------------------------------------------------------------------
  498. //
  499. // Function: CMachineNode::InitDataClass
  500. //
  501. // Synopsis: gets passed the IDataObject sent to the extension snapin for this
  502. // node, queries this IDataObject for the name of the machine
  503. // which this snapin is extending
  504. //
  505. // Arguments: None
  506. //
  507. // Returns: Nothing
  508. //
  509. // History: Created Header mmaguire 2/25/98 9:07 PM
  510. //
  511. //+---------------------------------------------------------------------------
  512. void CMachineNode::InitDataClass(IDataObject* pDataObject, CSnapInItem* pDefault)
  513. {
  514. TRACE_FUNCTION("CMachineNode::InitDataClass");
  515. // Check for preconditions.
  516. if( m_fAlreadyAnalyzedDataClass )
  517. {
  518. // We have already performed any work we needed to do with the dataobject here.
  519. return;
  520. }
  521. if (pDataObject == NULL)
  522. {
  523. return;
  524. }
  525. HRESULT hr;
  526. // OLECHAR szMachineName[IAS_MAX_COMPUTERNAME_LENGTH];
  527. // Try a large size because RRAS seems to want 2048
  528. OLECHAR szMachineName[4000];
  529. // Fill the structures which will tell the IDataObject what information
  530. // we want it to give us.
  531. STGMEDIUM stgmedium = { TYMED_HGLOBAL, NULL };
  532. FORMATETC formatetc = { m_CCF_MMC_SNAPIN_MACHINE_NAME,
  533. NULL,
  534. DVASPECT_CONTENT,
  535. -1,
  536. TYMED_HGLOBAL
  537. };
  538. // Allocate enough global memory for the IDataObject to write
  539. // the max computer name length.
  540. stgmedium.hGlobal = GlobalAlloc(0, sizeof(OLECHAR)*(IAS_MAX_COMPUTERNAME_LENGTH) );
  541. if (stgmedium.hGlobal == NULL)
  542. {
  543. return;
  544. }
  545. // Ask the IDataObject for the computer name.
  546. hr = pDataObject->GetDataHere(&formatetc, &stgmedium);
  547. if (SUCCEEDED(hr))
  548. {
  549. // Parse the data given back to us.
  550. // Create a stream on HGLOBAL
  551. CComPtr<IStream> spStream;
  552. hr = CreateStreamOnHGlobal(stgmedium.hGlobal, FALSE, &spStream);
  553. if (SUCCEEDED(hr))
  554. {
  555. // Read from the stream.
  556. unsigned long uWritten;
  557. hr = spStream->Read(szMachineName, sizeof(OLECHAR)*(IAS_MAX_COMPUTERNAME_LENGTH), &uWritten);
  558. if( SUCCEEDED(hr) )
  559. {
  560. m_bstrServerAddress = szMachineName;
  561. // check to see if we are configuring the local machine
  562. CString strLocalMachine;
  563. DWORD dwSize = MAX_COMPUTERNAME_LENGTH;
  564. ::GetComputerName(strLocalMachine.GetBuffer(dwSize), &dwSize);
  565. strLocalMachine.ReleaseBuffer();
  566. // If the machine name we read was either an empty string,
  567. // or it equals the name of the current computer,
  568. // then we are configuring the local machine.
  569. if ( ! szMachineName[0] || strLocalMachine.CompareNoCase(szMachineName) == 0)
  570. {
  571. m_bConfigureLocal = TRUE;
  572. }
  573. else
  574. m_bConfigureLocal = FALSE;
  575. }
  576. else
  577. {
  578. ShowErrorDialog( NULL, USE_DEFAULT, NULL, S_OK, USE_DEFAULT, GetComponentData()->m_spConsole );
  579. }
  580. }
  581. }
  582. GlobalFree(stgmedium.hGlobal);
  583. if( SUCCEEDED( hr ) )
  584. {
  585. // If we made it to here with an successful HRESULT, we have successfully analyzed
  586. // the IDataObject and we set this flag so that we don't do this work again.
  587. m_fAlreadyAnalyzedDataClass = TRUE;
  588. }
  589. }
  590. //////////////////////////////////////////////////////////////////////////////
  591. /*++
  592. CMachineNode::TaskNotify
  593. See CSnapinNode::TaskNotify (which this method overrides) for detailed info.
  594. --*/
  595. //////////////////////////////////////////////////////////////////////////////
  596. STDMETHODIMP CMachineNode::TaskNotify(
  597. IDataObject * pDataObject
  598. , VARIANT * pvarg
  599. , VARIANT * pvparam
  600. )
  601. {
  602. TRACE_FUNCTION("CMachineNode::TaskNotify");
  603. // Check for preconditions:
  604. // None.
  605. if ( !m_fSdoConnected )
  606. {
  607. return S_OK;
  608. }
  609. HRESULT hr = S_FALSE;
  610. if (pvarg->vt == VT_I4)
  611. {
  612. switch (pvarg->lVal)
  613. {
  614. case MACHINE_TASK__DEFINE_NETWORK_ACCESS_POLICY:
  615. hr = OnTaskPadDefineNetworkAccessPolicy( pDataObject, pvarg, pvparam );
  616. break;
  617. default:
  618. break;
  619. }
  620. }
  621. // ISSUE: What should I be returning here?
  622. return hr;
  623. }
  624. //////////////////////////////////////////////////////////////////////////////
  625. /*++
  626. CMachineNode::EnumTasks
  627. See CSnapinNode::EnumTasks (which this method overrides) for detailed info.
  628. --*/
  629. //////////////////////////////////////////////////////////////////////////////
  630. STDMETHODIMP CMachineNode::EnumTasks(
  631. IDataObject * pDataObject
  632. , BSTR szTaskGroup
  633. , IEnumTASK** ppEnumTASK
  634. )
  635. {
  636. TRACE_FUNCTION("CMachineNode::EnumTasks");
  637. // Check for preconditions:
  638. // None.
  639. if ( !m_fSdoConnected )
  640. {
  641. return S_OK;
  642. }
  643. HRESULT hr = S_OK;
  644. CMachineEnumTask * pMachineEnumTask = new CMachineEnumTask( this );
  645. if ( pMachineEnumTask == NULL )
  646. {
  647. hr = E_OUTOFMEMORY;
  648. }
  649. else
  650. {
  651. // Make sure release works properly on failure.
  652. pMachineEnumTask ->AddRef ();
  653. hr = pMachineEnumTask ->Init( pDataObject, szTaskGroup);
  654. if( hr == S_OK )
  655. {
  656. hr = pMachineEnumTask->QueryInterface( IID_IEnumTASK, (void **)ppEnumTASK );
  657. }
  658. pMachineEnumTask->Release();
  659. }
  660. return hr;
  661. }
  662. //////////////////////////////////////////////////////////////////////////////
  663. /*++
  664. CMachineNode::OnTaskPadDefineNetworkAccessPolicy
  665. Respond to the Define Network Access Policy taskpad command.
  666. --*/
  667. //////////////////////////////////////////////////////////////////////////////
  668. HRESULT CMachineNode::OnTaskPadDefineNetworkAccessPolicy(
  669. IDataObject * pDataObject
  670. , VARIANT * pvarg
  671. , VARIANT * pvparam
  672. )
  673. {
  674. TRACE_FUNCTION("CMachineNode::OnTaskPadDefineNetworkAccessPolicy");
  675. // Check for preconditions:
  676. // None.
  677. if ( !m_fSdoConnected )
  678. {
  679. return S_OK;
  680. }
  681. HRESULT hr = S_OK ;
  682. bool bDummy = TRUE;
  683. // Simulate a call to the OnNewPolicy message on the CPoliciesNode object,
  684. // just as if the user had clicked on New Policy
  685. _ASSERTE( m_pPoliciesNode != NULL );
  686. // The process command message will need a pointer to CSnapInObjectRoot
  687. CComponentData *pComponentData = GetComponentData();
  688. _ASSERTE( pComponentData != NULL );
  689. hr = m_pPoliciesNode->OnNewPolicy(
  690. bDummy // Not needed.
  691. , (CSnapInObjectRootBase *) pComponentData
  692. );
  693. return hr;
  694. }
  695. //////////////////////////////////////////////////////////////////////////////
  696. /*++
  697. CMachineNode::BeginConnectAction
  698. --*/
  699. //////////////////////////////////////////////////////////////////////////////
  700. HRESULT CMachineNode::BeginConnectAction( void )
  701. {
  702. TRACE_FUNCTION("CMachineNode::BeginConnectAction");
  703. HRESULT hr;
  704. if( NULL != m_pConnectionToServer )
  705. {
  706. // Already begun.
  707. return S_FALSE;
  708. }
  709. m_pConnectionToServer = new CConnectionToServer(
  710. this,
  711. m_bstrServerAddress,
  712. m_enumExtendedSnapin == INTERNET_AUTHENTICATION_SERVICE_SNAPIN
  713. );
  714. if( NULL == m_pConnectionToServer )
  715. {
  716. ShowErrorDialog( NULL, IDS_ERROR_CANT_CREATE_OBJECT, NULL, S_OK, USE_DEFAULT, GetComponentData()->m_spConsole );
  717. return E_OUTOFMEMORY;
  718. }
  719. m_pConnectionToServer->AddRef();
  720. // This starts the connect action off in another thread.
  721. CComponentData * pComponentData = GetComponentData();
  722. _ASSERTE( pComponentData != NULL );
  723. _ASSERTE( pComponentData->m_spConsole != NULL );
  724. HWND hWndMainWindow;
  725. hr = pComponentData->m_spConsole->GetMainWindow( &hWndMainWindow );
  726. _ASSERTE( SUCCEEDED( hr ) );
  727. _ASSERTE( NULL != hWndMainWindow );
  728. // This modeless dialog will take care of calling InitSdoPointers
  729. // when it is notified by the worker thread it creates that
  730. // the connect action got an SDO pointer.
  731. HWND hWndConnectDialog = m_pConnectionToServer->Create( hWndMainWindow );
  732. if( NULL == hWndConnectDialog )
  733. {
  734. // Error -- couldn't create window.
  735. ShowErrorDialog( NULL, USE_DEFAULT, NULL, S_OK, USE_DEFAULT, GetComponentData()->m_spConsole );
  736. return E_FAIL;
  737. }
  738. if ( m_enumExtendedSnapin != INTERNET_AUTHENTICATION_SERVICE_SNAPIN )
  739. {
  740. //
  741. // don't show the "Connecting ... " window for IAS, because IAS UI
  742. // already does that
  743. //
  744. // MAM 07/27/98 -- Don't show any connection window at all -- we will
  745. // change the policies icon to an hourglass.
  746. //pConnectionToServer->ShowWindow(SW_SHOW);
  747. }
  748. return S_OK;
  749. }
  750. //+---------------------------------------------------------------------------
  751. //
  752. // Function: CMachineNode::LoadSdoData
  753. //
  754. // Synopsis: load data from SDO
  755. //
  756. // Arguments: BOOL fDSAvailable -- is DS service available for this machine?
  757. //
  758. // Returns: HRESULT -
  759. //
  760. // History: Created Header byao 6/11/98 3:17:21 PM
  761. // Created for asynchrnous connect call
  762. //+---------------------------------------------------------------------------
  763. HRESULT CMachineNode::LoadSdoData(BOOL fDSAvailable)
  764. {
  765. TRACE_FUNCTION("CMachineNode::LoadSdoData");
  766. HRESULT hr = S_OK;
  767. m_fDSAvailable = fDSAvailable;
  768. // Retrieve the SDO interfaces that we obtained during the
  769. // connect action.
  770. // No smart pointers here -- prevents needless AddRefing and Releasing.
  771. ISdo* pSdoService;
  772. hr = m_pConnectionToServer->GetSdoService( &pSdoService );
  773. if( FAILED( hr ) || ! pSdoService )
  774. {
  775. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get service Sdo");
  776. return hr;
  777. }
  778. ISdoDictionaryOld * pSdoDictionaryOld;
  779. hr = m_pConnectionToServer->GetSdoDictionaryOld( &pSdoDictionaryOld );
  780. if( FAILED( hr ) || ! pSdoDictionaryOld )
  781. {
  782. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get dictionary Sdo");
  783. return hr;
  784. }
  785. #ifdef STORE_DATA_IN_DIRECTORY_SERVICE
  786. //
  787. // Is the server using Active Directory or the local machine?
  788. //
  789. CComVariant var;
  790. hr = spMachineSdo->GetProperty(PROPERTY_SERVER_USE_ACTIVE_DIRECTORY, &var);
  791. if ( FAILED(hr) )
  792. {
  793. ErrorTrace(ERROR_NAPMMC_MACHINENODE, "Can't get Server_Use_Active_Directory property, err = %x", hr);
  794. return hr;
  795. }
  796. _ASSERTE( V_VT(&var) == VT_BOOL );
  797. m_fUseActiveDirectory = (V_BOOL(&var)==VARIANT_TRUE);
  798. #endif // STORE_DATA_IN_DIRECTORY_SERVICE
  799. // Give the policies node the pointer to the policies sdo collection.
  800. if ( m_pPoliciesNode )
  801. {
  802. hr = m_pPoliciesNode->SetSdo(pSdoService,
  803. pSdoDictionaryOld,
  804. TRUE, // fSdoConnected,
  805. m_fUseActiveDirectory,
  806. m_fDSAvailable // fDSAvailable,
  807. );
  808. }
  809. m_fSdoConnected = TRUE;
  810. // We want to make sure all views get updated.
  811. CChangeNotification *pChangeNotification = new CChangeNotification();
  812. pChangeNotification->m_dwFlags = CHANGE_UPDATE_CHILDREN_OF_SELECTED_NODE;
  813. hr = GetComponentData()->m_spConsole->UpdateAllViews( NULL, (LPARAM) pChangeNotification, 0);
  814. pChangeNotification->Release();
  815. return hr;
  816. }