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.

1270 lines
40 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. croot.cpp
  7. DHCP root node information (the root node is not displayed
  8. in the MMC framework but contains information such as
  9. all of the servers in this snapin).
  10. FILE HISTORY:
  11. */
  12. #include "stdafx.h"
  13. #include "croot.h"
  14. #include "server.h"
  15. #include "tregkey.h"
  16. #include "service.h"
  17. #include "servbrow.h" // CAuthServerList
  18. #include "ncglobal.h" // network console global defines
  19. #include "addserv.h" // add server dialog
  20. #include <clusapi.h>
  21. #include "cluster.h" // cluster routines
  22. unsigned int g_cfMachineName = RegisterClipboardFormat(L"MMC_SNAPIN_MACHINE_NAME");
  23. #define ROOT_MESSAGE_MAX_STRING 6
  24. typedef enum _ROOT_MESSAGES
  25. {
  26. ROOT_MESSAGE_NO_SERVERS,
  27. ROOT_MESSAGE_MAX
  28. };
  29. UINT g_uRootMessages[ROOT_MESSAGE_MAX][ROOT_MESSAGE_MAX_STRING] =
  30. {
  31. {IDS_ROOT_MESSAGE_TITLE, Icon_Information, IDS_ROOT_MESSAGE_BODY1, IDS_ROOT_MESSAGE_BODY2, IDS_ROOT_MESSAGE_BODY3, 0},
  32. };
  33. /*---------------------------------------------------------------------------
  34. CDhcpRootHandler::CDhcpRootHandler
  35. Description
  36. Author: EricDav
  37. ---------------------------------------------------------------------------*/
  38. CDhcpRootHandler::CDhcpRootHandler(ITFSComponentData *pCompData)
  39. : CDhcpHandler(pCompData)
  40. {
  41. m_bMachineAdded = FALSE;
  42. m_fViewMessage = TRUE;
  43. }
  44. /*!--------------------------------------------------------------------------
  45. CDhcpRootHandler::InitializeNode
  46. Initializes node specific data
  47. Author: EricDav
  48. ---------------------------------------------------------------------------*/
  49. HRESULT
  50. CDhcpRootHandler::InitializeNode
  51. (
  52. ITFSNode * pNode
  53. )
  54. {
  55. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  56. CString strTemp;
  57. strTemp.LoadString(IDS_ROOT_NODENAME);
  58. SetDisplayName(strTemp);
  59. // Make the node immediately visible
  60. //pNode->SetVisibilityState(TFS_VIS_SHOW);
  61. pNode->SetData(TFS_DATA_COOKIE, 0);
  62. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_APPLICATION);
  63. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_APPLICATION);
  64. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  65. pNode->SetData(TFS_DATA_TYPE, DHCPSNAP_ROOT);
  66. SetColumnStringIDs(&aColumns[DHCPSNAP_ROOT][0]);
  67. SetColumnWidths(&aColumnWidths[DHCPSNAP_ROOT][0]);
  68. return hrOK;
  69. }
  70. /*---------------------------------------------------------------------------
  71. Overridden base handler functions
  72. ---------------------------------------------------------------------------*/
  73. /*!--------------------------------------------------------------------------
  74. CDhcpRootHandler::GetString
  75. Implementation of ITFSNodeHandler::GetString
  76. Author: KennT
  77. ---------------------------------------------------------------------------*/
  78. STDMETHODIMP_(LPCTSTR)
  79. CDhcpRootHandler::GetString
  80. (
  81. ITFSNode * pNode,
  82. int nCol
  83. )
  84. {
  85. if (nCol == 0 || nCol == -1)
  86. return GetDisplayName();
  87. else
  88. return NULL;
  89. }
  90. HRESULT
  91. CDhcpRootHandler::SetGroupName(LPCTSTR pszGroupName)
  92. {
  93. CString strSnapinBaseName, strGroupName, szBuf;
  94. {
  95. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  96. strSnapinBaseName.LoadString(IDS_ROOT_NODENAME);
  97. }
  98. strGroupName = pszGroupName;
  99. if (strGroupName.IsEmpty())
  100. szBuf = strSnapinBaseName;
  101. else
  102. szBuf.Format(_T("%s [%s]"), strSnapinBaseName, strGroupName);
  103. SetDisplayName(szBuf);
  104. return hrOK;
  105. }
  106. HRESULT
  107. CDhcpRootHandler::GetGroupName(CString * pstrGroupName)
  108. {
  109. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  110. CString strSnapinBaseName, strDisplayName;
  111. strSnapinBaseName.LoadString(IDS_ROOT_NODENAME);
  112. int nBaseLength = strSnapinBaseName.GetLength() + 1; // For the space
  113. strDisplayName = GetDisplayName();
  114. if (strDisplayName.GetLength() == nBaseLength)
  115. pstrGroupName->Empty();
  116. else
  117. *pstrGroupName = strDisplayName.Right(strDisplayName.GetLength() - nBaseLength);
  118. return hrOK;
  119. }
  120. /*---------------------------------------------------------------------------
  121. CDhcpRootHandler::OnExpand
  122. Handles enumeration of a scope item
  123. Author: EricDav
  124. ---------------------------------------------------------------------------*/
  125. HRESULT
  126. CDhcpRootHandler::OnExpand
  127. (
  128. ITFSNode * pNode,
  129. LPDATAOBJECT pDataObject,
  130. DWORD dwType,
  131. LPARAM arg,
  132. LPARAM param
  133. )
  134. {
  135. HRESULT hr = hrOK;
  136. if (m_bExpanded)
  137. return hr;
  138. // do the default handling
  139. hr = CDhcpHandler::OnExpand(pNode, pDataObject, dwType, arg, param);
  140. if (dwType & TFS_COMPDATA_EXTENSION)
  141. {
  142. // we are extending somebody. Get the computer name and check that machine
  143. hr = CheckMachine(pNode, pDataObject);
  144. }
  145. else
  146. {
  147. int nVisible, nTotal;
  148. hr = pNode->GetChildCount(&nVisible, &nTotal);
  149. // only possibly add the local machine if the list is currently empty
  150. if (nTotal == 0)
  151. {
  152. // check to see if we need to add the local machine to the list
  153. hr = CheckMachine(pNode, NULL);
  154. }
  155. }
  156. return hr;
  157. }
  158. /*---------------------------------------------------------------------------
  159. CDhcpRootHandler::OnAddMenuItems
  160. Description
  161. Author: EricDav
  162. ---------------------------------------------------------------------------*/
  163. STDMETHODIMP
  164. CDhcpRootHandler::OnAddMenuItems
  165. (
  166. ITFSNode * pNode,
  167. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  168. LPDATAOBJECT lpDataObject,
  169. DATA_OBJECT_TYPES type,
  170. DWORD dwType,
  171. long * pInsertionAllowed
  172. )
  173. {
  174. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  175. HRESULT hr = S_OK;
  176. CString strMenuItem;
  177. if (type == CCT_SCOPE)
  178. {
  179. // these menu items go in the new menu,
  180. // only visible from scope pane
  181. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  182. {
  183. strMenuItem.LoadString(IDS_ADD_SERVER);
  184. hr = LoadAndAddMenuItem( pContextMenuCallback,
  185. strMenuItem,
  186. IDS_ADD_SERVER,
  187. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  188. 0 );
  189. ASSERT( SUCCEEDED(hr) );
  190. strMenuItem.LoadString(IDS_BROWSE_SERVERS);
  191. hr = LoadAndAddMenuItem( pContextMenuCallback,
  192. strMenuItem,
  193. IDS_BROWSE_SERVERS,
  194. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  195. 0 );
  196. ASSERT( SUCCEEDED(hr) );
  197. if (OldServerListExists())
  198. {
  199. // these menu items go in the new menu,
  200. // only visible from scope pane
  201. strMenuItem.LoadString(IDS_IMPORT_OLD_LIST);
  202. hr = LoadAndAddMenuItem( pContextMenuCallback,
  203. strMenuItem,
  204. IDS_IMPORT_OLD_LIST,
  205. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  206. 0 );
  207. ASSERT( SUCCEEDED(hr) );
  208. }
  209. }
  210. }
  211. return hr;
  212. }
  213. /*!--------------------------------------------------------------------------
  214. CDhcpRootHandler::AddMenuItems
  215. Over-ride this to add our view menu item
  216. Author: EricDav
  217. ---------------------------------------------------------------------------*/
  218. STDMETHODIMP
  219. CDhcpRootHandler::AddMenuItems
  220. (
  221. ITFSComponent * pComponent,
  222. MMC_COOKIE cookie,
  223. LPDATAOBJECT pDataObject,
  224. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  225. long * pInsertionAllowed
  226. )
  227. {
  228. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  229. HRESULT hr = S_OK;
  230. CString strMenuItem;
  231. // figure out if we need to pass this to the scope pane menu handler
  232. hr = HandleScopeMenus(cookie, pDataObject, pContextMenuCallback, pInsertionAllowed);
  233. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW)
  234. {
  235. strMenuItem.LoadString(IDS_MESSAGE_VIEW);
  236. hr = LoadAndAddMenuItem( pContextMenuCallback,
  237. strMenuItem,
  238. IDS_MESSAGE_VIEW,
  239. CCM_INSERTIONPOINTID_PRIMARY_VIEW,
  240. (m_fViewMessage) ? MF_CHECKED : 0 );
  241. }
  242. return hr;
  243. }
  244. /*---------------------------------------------------------------------------
  245. CDhcpRootHandler::OnCommand
  246. Description
  247. Author: EricDav
  248. ---------------------------------------------------------------------------*/
  249. STDMETHODIMP
  250. CDhcpRootHandler::OnCommand
  251. (
  252. ITFSNode * pNode,
  253. long nCommandId,
  254. DATA_OBJECT_TYPES type,
  255. LPDATAOBJECT pDataObject,
  256. DWORD dwType
  257. )
  258. {
  259. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  260. HRESULT hr = S_OK;
  261. switch (nCommandId)
  262. {
  263. case IDS_ADD_SERVER:
  264. hr = OnCreateNewServer(pNode);
  265. break;
  266. case IDS_BROWSE_SERVERS:
  267. hr = OnBrowseServers(pNode);
  268. break;
  269. case IDS_IMPORT_OLD_LIST:
  270. hr = OnImportOldList(pNode);
  271. break;
  272. default:
  273. break;
  274. }
  275. return hr;
  276. }
  277. /*!--------------------------------------------------------------------------
  278. CDhcpRootHandler::Command
  279. Handles commands for the current view
  280. Author: EricDav
  281. ---------------------------------------------------------------------------*/
  282. STDMETHODIMP
  283. CDhcpRootHandler::Command
  284. (
  285. ITFSComponent * pComponent,
  286. MMC_COOKIE cookie,
  287. int nCommandID,
  288. LPDATAOBJECT pDataObject
  289. )
  290. {
  291. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  292. HRESULT hr = S_OK;
  293. SPITFSNode spNode;
  294. switch (nCommandID)
  295. {
  296. case MMCC_STANDARD_VIEW_SELECT:
  297. break;
  298. case IDS_MESSAGE_VIEW:
  299. m_fViewMessage = !m_fViewMessage;
  300. m_spNodeMgr->GetRootNode(&spNode);
  301. UpdateResultMessage(spNode);
  302. break;
  303. // this may have come from the scope pane handler, so pass it up
  304. default:
  305. hr = HandleScopeCommand(cookie, nCommandID, pDataObject);
  306. break;
  307. }
  308. return hr;
  309. }
  310. /*!--------------------------------------------------------------------------
  311. CDhcpRootHandler::HasPropertyPages
  312. Implementation of ITFSNodeHandler::HasPropertyPages
  313. NOTE: the root node handler has to over-ride this function to
  314. handle the snapin manager property page (wizard) case!!!
  315. Author: KennT
  316. ---------------------------------------------------------------------------*/
  317. STDMETHODIMP
  318. CDhcpRootHandler::HasPropertyPages
  319. (
  320. ITFSNode * pNode,
  321. LPDATAOBJECT pDataObject,
  322. DATA_OBJECT_TYPES type,
  323. DWORD dwType
  324. )
  325. {
  326. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  327. HRESULT hr = hrOK;
  328. if (dwType & TFS_COMPDATA_CREATE)
  329. {
  330. // This is the case where we are asked to bring up property
  331. // pages when the user is adding a new snapin. These calls
  332. // are forwarded to the root node to handle.
  333. hr = hrFalse;
  334. }
  335. else
  336. {
  337. // we have property pages in the normal case
  338. hr = hrFalse;
  339. }
  340. return hr;
  341. }
  342. /*---------------------------------------------------------------------------
  343. CDhcpRootHandler::CreatePropertyPages
  344. Description
  345. Author: EricDav
  346. ---------------------------------------------------------------------------*/
  347. STDMETHODIMP
  348. CDhcpRootHandler::CreatePropertyPages
  349. (
  350. ITFSNode * pNode,
  351. LPPROPERTYSHEETCALLBACK lpProvider,
  352. LPDATAOBJECT pDataObject,
  353. LONG_PTR handle,
  354. DWORD dwType
  355. )
  356. {
  357. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  358. HRESULT hr = hrOK;
  359. HPROPSHEETPAGE hPage;
  360. Assert(pNode->GetData(TFS_DATA_COOKIE) == 0);
  361. if (dwType & TFS_COMPDATA_CREATE)
  362. {
  363. //
  364. // We are loading this snapin for the first time, put up a property
  365. // page to allow them to name this thing.
  366. //
  367. }
  368. else
  369. {
  370. //
  371. // Object gets deleted when the page is destroyed
  372. //
  373. }
  374. return hr;
  375. }
  376. /*---------------------------------------------------------------------------
  377. CDhcpRootHandler::OnPropertyChange
  378. Description
  379. Author: EricDav
  380. ---------------------------------------------------------------------------*/
  381. HRESULT
  382. CDhcpRootHandler::OnPropertyChange
  383. (
  384. ITFSNode * pNode,
  385. LPDATAOBJECT pDataobject,
  386. DWORD dwType,
  387. LPARAM arg,
  388. LPARAM lParam
  389. )
  390. {
  391. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  392. return hrOK;
  393. }
  394. HRESULT
  395. CDhcpRootHandler::OnRemoveChildren(
  396. ITFSNode * pNode,
  397. LPDATAOBJECT pDataObject,
  398. LPARAM arg,
  399. LPARAM param
  400. )
  401. {
  402. HRESULT hr = hrOK;
  403. SPITFSNodeEnum spNodeEnum;
  404. SPITFSNode spCurrentNode;
  405. ULONG nNumReturned = 0;
  406. if (!m_bExpanded)
  407. return hr;
  408. m_bExpanded = FALSE;
  409. // do the default handling
  410. hr = CDhcpHandler::OnRemoveChildren(pNode, pDataObject, arg, param);
  411. // get the enumerator for this node
  412. CORg(pNode->GetEnum(&spNodeEnum));
  413. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  414. // walk the list of child nodes and remove each node
  415. while (nNumReturned)
  416. {
  417. CORg (pNode->RemoveChild(spCurrentNode));
  418. spCurrentNode.Release();
  419. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  420. }
  421. Error:
  422. return hr;
  423. }
  424. /*---------------------------------------------------------------------------
  425. CDhcpRootHandler::OnGetResultViewType
  426. Return the result view that this node is going to support
  427. Author: EricDav
  428. ---------------------------------------------------------------------------*/
  429. HRESULT
  430. CDhcpRootHandler::OnGetResultViewType
  431. (
  432. ITFSComponent * pComponent,
  433. MMC_COOKIE cookie,
  434. LPOLESTR * ppViewType,
  435. long * pViewOptions
  436. )
  437. {
  438. return CDhcpHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions);
  439. }
  440. /*!--------------------------------------------------------------------------
  441. CDhcpRootHandler::OnResultSelect
  442. For nodes with task pads, we override the select message to set
  443. the selected node. Nodes with taskpads do not get the MMCN_SHOW
  444. message which is where we normall set the selected node
  445. Author: EricDav
  446. ---------------------------------------------------------------------------*/
  447. HRESULT CDhcpRootHandler::OnResultSelect(ITFSComponent *pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  448. {
  449. HRESULT hr = hrOK;
  450. SPITFSNode spRootNode;
  451. if ( 0 == HIWORD( arg )) {
  452. return S_FALSE;
  453. }
  454. CORg(CDhcpHandler::OnResultSelect(pComponent, pDataObject, cookie, arg, lParam));
  455. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  456. UpdateResultMessage(spRootNode);
  457. Error:
  458. return hr;
  459. }
  460. void CDhcpRootHandler::UpdateResultMessage(ITFSNode * pNode)
  461. {
  462. HRESULT hr = hrOK;
  463. int nMessage = ROOT_MESSAGE_NO_SERVERS; // default
  464. int nVisible, nTotal;
  465. int i;
  466. CString strTitle, strBody, strTemp;
  467. if (!m_fViewMessage)
  468. {
  469. ClearMessage(pNode);
  470. }
  471. else
  472. {
  473. CORg(pNode->GetChildCount(&nVisible, &nTotal));
  474. if (nTotal > 0)
  475. {
  476. ClearMessage(pNode);
  477. }
  478. else
  479. {
  480. nMessage = ROOT_MESSAGE_NO_SERVERS;
  481. // now build the text strings
  482. // first entry is the title
  483. strTitle.LoadString(g_uRootMessages[nMessage][0]);
  484. // second entry is the icon
  485. // third ... n entries are the body strings
  486. for (i = 2; g_uRootMessages[nMessage][i] != 0; i++)
  487. {
  488. strTemp.LoadString(g_uRootMessages[nMessage][i]);
  489. strBody += strTemp;
  490. }
  491. ShowMessage(pNode, strTitle, strBody, (IconIdentifier) g_uRootMessages[nMessage][1]);
  492. }
  493. }
  494. Error:
  495. return;
  496. }
  497. /*---------------------------------------------------------------------------
  498. Command handlers
  499. ---------------------------------------------------------------------------*/
  500. /*---------------------------------------------------------------------------
  501. CDhcpRootHandler::OnCreateNewServer
  502. Description
  503. Author: EricDav
  504. ---------------------------------------------------------------------------*/
  505. HRESULT
  506. CDhcpRootHandler::OnCreateNewServer
  507. (
  508. ITFSNode * pNode
  509. )
  510. {
  511. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  512. HRESULT hr = hrOK;
  513. CAddServer dlgAddServer;
  514. BOOL fServerAdded = FALSE;
  515. dlgAddServer.SetServerList(&g_AuthServerList);
  516. if (dlgAddServer.DoModal() == IDOK)
  517. {
  518. while ( !dlgAddServer.m_lSelSrv.IsEmpty()) {
  519. SelectedServer SelSrv = dlgAddServer.m_lSelSrv.RemoveHead();
  520. if ( !IsServerInList( pNode, ::UtilCvtWstrToIpAddr( SelSrv.strIp ),
  521. SelSrv.strName )) {
  522. AddServer( SelSrv.strIp, SelSrv.strName, TRUE );
  523. fServerAdded = TRUE;
  524. }
  525. } // while
  526. } // if
  527. if (fServerAdded) {
  528. UpdateResultMessage(pNode);
  529. }
  530. return hr;
  531. }
  532. /*---------------------------------------------------------------------------
  533. CDhcpRootHandler::OnBrowseServers
  534. Description
  535. Author: EricDav
  536. ---------------------------------------------------------------------------*/
  537. HRESULT
  538. CDhcpRootHandler::OnBrowseServers
  539. (
  540. ITFSNode * pNode
  541. )
  542. {
  543. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  544. HRESULT hr = hrOK;
  545. CServerBrowse dlgBrowse;
  546. BOOL fServerAdded = FALSE;
  547. BEGIN_WAIT_CURSOR;
  548. if (!g_AuthServerList.IsInitialized())
  549. {
  550. hr = g_AuthServerList.Init();
  551. hr = g_AuthServerList.EnumServers();
  552. }
  553. dlgBrowse.SetServerList(&g_AuthServerList);
  554. END_WAIT_CURSOR;
  555. if (dlgBrowse.DoModal() == IDOK)
  556. {
  557. for (int i = 0; i < dlgBrowse.m_astrName.GetSize(); i++)
  558. {
  559. if (IsServerInList(pNode, ::UtilCvtWstrToIpAddr(dlgBrowse.m_astrIp[i]), dlgBrowse.m_astrName[i]))
  560. {
  561. DhcpMessageBox(IDS_ERR_HOST_ALREADY_CONNECTED);
  562. }
  563. else
  564. {
  565. AddServer(dlgBrowse.m_astrIp[i],
  566. dlgBrowse.m_astrName[i],
  567. TRUE);
  568. fServerAdded = TRUE;
  569. }
  570. }
  571. }
  572. if (fServerAdded)
  573. UpdateResultMessage(pNode);
  574. return hr;
  575. }
  576. /*---------------------------------------------------------------------------
  577. CDhcpRootHandler::OnImportOldList
  578. Description
  579. Author: EricDav
  580. ---------------------------------------------------------------------------*/
  581. HRESULT
  582. CDhcpRootHandler::OnImportOldList
  583. (
  584. ITFSNode * pNode
  585. )
  586. {
  587. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  588. DWORD err = LoadOldServerList(pNode);
  589. if (err)
  590. ::DhcpMessageBox(err);
  591. return err;
  592. }
  593. /*---------------------------------------------------------------------------
  594. CDhcpRootHandler::CreateLocalDhcpServer
  595. Description
  596. Author: EricDav
  597. ---------------------------------------------------------------------------*/
  598. void
  599. CDhcpRootHandler::CreateLocalDhcpServer()
  600. {
  601. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  602. CString strName;
  603. // Create the local machine
  604. //
  605. strName.LoadString (IDS_LOOPBACK_IP_ADDR);
  606. AddServer(strName, NULL, TRUE);
  607. }
  608. /*---------------------------------------------------------------------------
  609. CDhcpRootHandler::AddServer
  610. Description
  611. Author: EricDav
  612. ---------------------------------------------------------------------------*/
  613. HRESULT
  614. CDhcpRootHandler::AddServer
  615. (
  616. LPCWSTR pServerIp,
  617. LPCTSTR pServerName,
  618. BOOL bNewServer,
  619. DWORD dwServerOptions,
  620. DWORD dwRefreshInterval,
  621. BOOL bExtension
  622. )
  623. {
  624. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  625. HRESULT hr = hrOK;
  626. CDhcpServer * pDhcpServer = NULL;
  627. SPITFSNodeHandler spHandler;
  628. SPITFSNode spNode, spRootNode;
  629. // Create a handler for the node
  630. try
  631. {
  632. pDhcpServer = new CDhcpServer(m_spTFSCompData, pServerIp);
  633. pDhcpServer->SetName(pServerName);
  634. // Do this so that it will get released correctly
  635. spHandler = pDhcpServer;
  636. }
  637. catch(...)
  638. {
  639. hr = E_OUTOFMEMORY;
  640. }
  641. CORg( hr );
  642. //
  643. // Create the server container information
  644. //
  645. CreateContainerTFSNode(&spNode,
  646. &GUID_DhcpServerNodeType,
  647. pDhcpServer,
  648. pDhcpServer,
  649. m_spNodeMgr);
  650. // Tell the handler to initialize any specific data
  651. pDhcpServer->InitializeNode((ITFSNode *) spNode);
  652. // tell the server to set the name differently in the extension case
  653. if (dwServerOptions & SERVER_OPTION_EXTENSION)
  654. {
  655. m_bMachineAdded = TRUE;
  656. pDhcpServer->SetExtensionName();
  657. }
  658. // Mask out the auto refresh option because we set it next
  659. pDhcpServer->SetServerOptions(dwServerOptions & ~SERVER_OPTION_AUTO_REFRESH);
  660. // if we got a valid refresh interval, then set it.
  661. if (dwRefreshInterval != 0xffffffff)
  662. pDhcpServer->SetAutoRefresh(spNode, dwServerOptions & SERVER_OPTION_AUTO_REFRESH, dwRefreshInterval);
  663. AddServerSortedName(spNode, bNewServer);
  664. if (bNewServer)
  665. {
  666. // need to get our node descriptor
  667. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  668. spRootNode->SetData(TFS_DATA_DIRTY, TRUE);
  669. }
  670. Error:
  671. return hr;
  672. }
  673. /*---------------------------------------------------------------------------
  674. CDhcpRootHandler::IsServerInList
  675. Description
  676. Author: EricDav
  677. ---------------------------------------------------------------------------*/
  678. BOOL
  679. CDhcpRootHandler::IsServerInList
  680. (
  681. ITFSNode * pRootNode,
  682. DHCP_IP_ADDRESS dhcpIpAddressNew,
  683. CString & strName
  684. )
  685. {
  686. HRESULT hr = hrOK;
  687. SPITFSNodeEnum spNodeEnum;
  688. SPITFSNode spCurrentNode;
  689. ULONG nNumReturned = 0;
  690. DHCP_IP_ADDRESS dhcpIpAddressCurrent;
  691. BOOL bFound = FALSE;
  692. CString strCurrentName;
  693. // get the enumerator for this node
  694. pRootNode->GetEnum(&spNodeEnum);
  695. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  696. while (nNumReturned)
  697. {
  698. // walk the list of servers and see if it already exists
  699. CDhcpServer * pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  700. pServer->GetIpAddress(&dhcpIpAddressCurrent);
  701. //if (dhcpIpAddressCurrent == dhcpIpAddressNew)
  702. strCurrentName = pServer->GetName();
  703. if (!strCurrentName.IsEmpty() &&
  704. strName.CompareNoCase(strCurrentName) == 0)
  705. {
  706. bFound = TRUE;
  707. break;
  708. }
  709. // get the next Server in the list
  710. spCurrentNode.Release();
  711. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  712. }
  713. return bFound;
  714. }
  715. /*---------------------------------------------------------------------------
  716. CDhcpRootHandler::OldServerListExists
  717. Description
  718. Author: EricDav
  719. ---------------------------------------------------------------------------*/
  720. BOOL
  721. CDhcpRootHandler::OldServerListExists()
  722. {
  723. RegKey rk;
  724. LONG err;
  725. BOOL bExists = TRUE;
  726. CStringList strList;
  727. err = rk.Open(HKEY_CURRENT_USER, DHCP_REG_USER_KEY_NAME);
  728. if (err != ERROR_SUCCESS)
  729. {
  730. // the key doesn't exist, so there's nothing to import...
  731. // just return ok
  732. bExists = FALSE;
  733. }
  734. err = rk.QueryValue(DHCP_REG_VALUE_HOSTS, strList);
  735. if (err != ERROR_SUCCESS)
  736. bExists = FALSE;
  737. return bExists;
  738. }
  739. /*---------------------------------------------------------------------------
  740. CDhcpRootHandler::LoadOldServerList
  741. Description
  742. Author: EricDav
  743. ---------------------------------------------------------------------------*/
  744. DWORD
  745. CDhcpRootHandler::LoadOldServerList
  746. (
  747. ITFSNode * pNode
  748. )
  749. {
  750. RegKey rk;
  751. CStringList strList ;
  752. CString * pstr ;
  753. POSITION pos ;
  754. LONG err;
  755. BOOL bServerAdded = FALSE;
  756. CString strName;
  757. DHC_HOST_INFO_STRUCT hostInfo;
  758. err = rk.Open(HKEY_CURRENT_USER, DHCP_REG_USER_KEY_NAME);
  759. if (err == ERROR_FILE_NOT_FOUND)
  760. {
  761. // the key doesn't exist, so there's nothing to import...
  762. // just return ok
  763. return ERROR_SUCCESS;
  764. }
  765. else
  766. if (err)
  767. return err;
  768. do
  769. {
  770. if ( err = rk.QueryValue( DHCP_REG_VALUE_HOSTS, strList ) )
  771. {
  772. break ;
  773. }
  774. pos = strList.GetHeadPosition();
  775. if (pos == NULL)
  776. break;
  777. for ( ; pos && (pstr = & strList.GetNext(pos)); /**/ )
  778. {
  779. DHCP_IP_ADDRESS dhcpIpAddress = UtilCvtWstrToIpAddr(*pstr);
  780. err = ::UtilGetHostInfo(dhcpIpAddress, &hostInfo);
  781. if (err == ERROR_SUCCESS)
  782. {
  783. strName = hostInfo._chHostName;
  784. }
  785. // check to see if the server already is in the list
  786. // if not then add
  787. if (!IsServerInList(pNode, dhcpIpAddress, strName))
  788. {
  789. // is this a local machine addr? Convert to real IP
  790. if ((dhcpIpAddress & 0xFF000000) == 127)
  791. {
  792. UtilGetLocalHostAddress(&dhcpIpAddress);
  793. UtilCvtIpAddrToWstr(dhcpIpAddress, pstr);
  794. }
  795. AddServer(*pstr, strName, TRUE, 0, DHCPSNAP_REFRESH_INTERVAL_DEFAULT);
  796. bServerAdded = TRUE;
  797. }
  798. }
  799. }
  800. while ( FALSE ) ;
  801. //
  802. // Set the dirty flag if we added anything to the list
  803. //
  804. if (bServerAdded)
  805. pNode->SetData(TFS_DATA_DIRTY, TRUE);
  806. //
  807. // This isn't really an error -- it just means that we didn't
  808. // find the key name in the list
  809. //
  810. if (err == ERROR_FILE_NOT_FOUND)
  811. {
  812. Trace0("Didn't find old addresses registry key -- starting from scratch");
  813. err = ERROR_SUCCESS;
  814. }
  815. return err ;
  816. }
  817. /*---------------------------------------------------------------------------
  818. CDhcpRootHandler::AddServerSortedIp
  819. Description
  820. Author: EricDav
  821. ---------------------------------------------------------------------------*/
  822. HRESULT
  823. CDhcpRootHandler::AddServerSortedIp
  824. (
  825. ITFSNode * pNewNode,
  826. BOOL bNewServer
  827. )
  828. {
  829. HRESULT hr = hrOK;
  830. SPITFSNodeEnum spNodeEnum;
  831. SPITFSNode spCurrentNode;
  832. SPITFSNode spPrevNode;
  833. SPITFSNode spRootNode;
  834. ULONG nNumReturned = 0;
  835. DHCP_IP_ADDRESS dhcpIpAddressCurrent = 0;
  836. DHCP_IP_ADDRESS dhcpIpAddressTarget;
  837. CDhcpServer * pServer;
  838. // get our target address
  839. pServer = GETHANDLER(CDhcpServer, pNewNode);
  840. pServer->GetIpAddress(&dhcpIpAddressTarget);
  841. // need to get our node descriptor
  842. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  843. // get the enumerator for this node
  844. CORg(spRootNode->GetEnum(&spNodeEnum));
  845. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  846. while (nNumReturned)
  847. {
  848. // walk the list of servers and see if it already exists
  849. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  850. pServer->GetIpAddress(&dhcpIpAddressCurrent);
  851. if (dhcpIpAddressCurrent > dhcpIpAddressTarget)
  852. {
  853. // Found where we need to put it, break out
  854. break;
  855. }
  856. // get the next Server in the list
  857. spPrevNode.Set(spCurrentNode);
  858. spCurrentNode.Release();
  859. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  860. }
  861. // Add the node in based on the PrevNode pointer
  862. if (spPrevNode)
  863. {
  864. if (bNewServer)
  865. {
  866. if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL)
  867. {
  868. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS);
  869. pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID));
  870. }
  871. }
  872. CORg(spRootNode->InsertChild(spPrevNode, pNewNode));
  873. }
  874. else
  875. {
  876. // add to the head
  877. if (m_bExpanded)
  878. {
  879. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_FIRST);
  880. }
  881. CORg(spRootNode->AddChild(pNewNode));
  882. }
  883. Error:
  884. return hr;
  885. }
  886. /*---------------------------------------------------------------------------
  887. CDhcpRootHandler::AddServerSortedName
  888. Description
  889. Author: EricDav
  890. ---------------------------------------------------------------------------*/
  891. HRESULT
  892. CDhcpRootHandler::AddServerSortedName
  893. (
  894. ITFSNode * pNewNode,
  895. BOOL bNewServer
  896. )
  897. {
  898. HRESULT hr = hrOK;
  899. SPITFSNodeEnum spNodeEnum;
  900. SPITFSNode spCurrentNode;
  901. SPITFSNode spPrevNode;
  902. SPITFSNode spRootNode;
  903. ULONG nNumReturned = 0;
  904. CString strTarget, strCurrent;
  905. CDhcpServer * pServer;
  906. // get our target address
  907. pServer = GETHANDLER(CDhcpServer, pNewNode);
  908. strTarget = pServer->GetName();
  909. // need to get our node descriptor
  910. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  911. // get the enumerator for this node
  912. CORg(spRootNode->GetEnum(&spNodeEnum));
  913. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  914. while (nNumReturned)
  915. {
  916. // walk the list of servers and see if it already exists
  917. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  918. strCurrent = pServer->GetName();
  919. if (strTarget.CompareNoCase(strCurrent) < 0)
  920. {
  921. // Found where we need to put it, break out
  922. break;
  923. }
  924. // get the next Server in the list
  925. spPrevNode.Set(spCurrentNode);
  926. spCurrentNode.Release();
  927. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  928. }
  929. // Add the node in based on the PrevNode pointer
  930. if (spPrevNode)
  931. {
  932. if (bNewServer)
  933. {
  934. if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL)
  935. {
  936. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS);
  937. pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID));
  938. }
  939. }
  940. CORg(spRootNode->InsertChild(spPrevNode, pNewNode));
  941. }
  942. else
  943. {
  944. // add to the head
  945. if (m_bExpanded)
  946. {
  947. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_FIRST);
  948. }
  949. CORg(spRootNode->AddChild(pNewNode));
  950. }
  951. Error:
  952. return hr;
  953. }
  954. /*---------------------------------------------------------------------------
  955. CDhcpRootHandler::CheckMachine
  956. Checks to see if the DHCP server service is running on the local
  957. machine. If it is, it adds it to the list of servers.
  958. Author: EricDav
  959. ---------------------------------------------------------------------------*/
  960. HRESULT
  961. CDhcpRootHandler::CheckMachine
  962. (
  963. ITFSNode * pRootNode,
  964. LPDATAOBJECT pDataObject
  965. )
  966. {
  967. HRESULT hr = hrOK;
  968. // Get the local machine name and check to see if the service
  969. // is installed.
  970. CString strMachineName;
  971. LPTSTR pBuf;
  972. DWORD dwLength = MAX_COMPUTERNAME_LENGTH + 1;
  973. BOOL bExtension = (pDataObject != NULL);
  974. BOOL fInCluster = FALSE;
  975. CString strLocalIp, strLocalName, strIp;
  976. DHC_HOST_INFO_STRUCT hostInfo;
  977. DHCP_IP_ADDRESS dhcpAddress;
  978. if (!bExtension)
  979. {
  980. // just check the local machine
  981. pBuf = strMachineName.GetBuffer(dwLength);
  982. GetComputerName(pBuf, &dwLength);
  983. strMachineName.ReleaseBuffer();
  984. UtilGetLocalHostAddress(&dhcpAddress);
  985. }
  986. else
  987. {
  988. // get the machine name from the data object
  989. strMachineName = Extract<TCHAR>(pDataObject, (CLIPFORMAT) g_cfMachineName, COMPUTERNAME_LEN_MAX);
  990. UtilGetHostAddress(strMachineName, &dhcpAddress);
  991. RemoveOldEntries(pRootNode, dhcpAddress);
  992. }
  993. fInCluster = ::FIsComputerInRunningCluster(strMachineName);
  994. if (fInCluster)
  995. {
  996. if (GetClusterResourceIp(strMachineName, _T("DHCP Service"), strIp) == ERROR_SUCCESS)
  997. {
  998. dhcpAddress = ::UtilCvtWstrToIpAddr(strIp);
  999. }
  1000. }
  1001. if (fInCluster)
  1002. {
  1003. // get the resource name for the IP address we just got
  1004. UtilGetHostInfo(dhcpAddress, &hostInfo);
  1005. strMachineName = hostInfo._chHostName;
  1006. }
  1007. // check to see if the service is running
  1008. BOOL bServiceRunning;
  1009. DWORD dwError = ::TFSIsServiceRunning(strMachineName, _T("DHCPServer"), &bServiceRunning);
  1010. if (dwError != ERROR_SUCCESS ||
  1011. !bServiceRunning)
  1012. {
  1013. // The following condition could happen to get here:
  1014. // o The service is not installed.
  1015. // o Couldn't access for some reason.
  1016. // o The service isn't running.
  1017. // Don't add to the list.
  1018. return hrOK;
  1019. }
  1020. if (!fInCluster)
  1021. {
  1022. UtilGetHostInfo(dhcpAddress, &hostInfo);
  1023. strMachineName = hostInfo._chHostName;
  1024. }
  1025. // OK. The service is installed, so lets and add it to the list.
  1026. if (IsServerInList(pRootNode, dhcpAddress, strMachineName))
  1027. return hr;
  1028. // looks good, add to list
  1029. UtilCvtIpAddrToWstr(dhcpAddress, &strLocalIp);
  1030. DWORD dwFlags = SERVER_OPTION_SHOW_ROGUE;
  1031. if (bExtension)
  1032. dwFlags |= SERVER_OPTION_EXTENSION;
  1033. AddServer(strLocalIp, strMachineName, TRUE, dwFlags, DHCPSNAP_REFRESH_INTERVAL_DEFAULT, bExtension);
  1034. m_bMachineAdded = TRUE;
  1035. return hr;
  1036. }
  1037. // when running as an extension, it is possible that we were saved as "local machine"
  1038. // which means that if the saved console file was moved to another machine we need to remove
  1039. // the old entry that was saved
  1040. HRESULT
  1041. CDhcpRootHandler::RemoveOldEntries(ITFSNode * pNode, DHCP_IP_ADDRESS dhcpAddress)
  1042. {
  1043. HRESULT hr = hrOK;
  1044. SPITFSNodeEnum spNodeEnum;
  1045. SPITFSNode spCurrentNode;
  1046. ULONG nNumReturned = 0;
  1047. CDhcpServer * pServer;
  1048. // get the enumerator for this node
  1049. CORg(pNode->GetEnum(&spNodeEnum));
  1050. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  1051. while (nNumReturned)
  1052. {
  1053. // walk the list of servers and see if it already exists
  1054. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  1055. DHCP_IP_ADDRESS ipaddrCurrent;
  1056. pServer->GetIpAddress(&ipaddrCurrent);
  1057. //if (ipaddrCurrent != dhcpAddress)
  1058. {
  1059. CORg (pNode->RemoveChild(spCurrentNode));
  1060. }
  1061. spCurrentNode.Release();
  1062. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1063. }
  1064. Error:
  1065. return hr;
  1066. }