Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1225 lines
31 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. HRESULT 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. /*---------------------------------------------------------------------------
  395. CDhcpRootHandler::OnGetResultViewType
  396. Return the result view that this node is going to support
  397. Author: EricDav
  398. ---------------------------------------------------------------------------*/
  399. HRESULT
  400. CDhcpRootHandler::OnGetResultViewType
  401. (
  402. ITFSComponent * pComponent,
  403. MMC_COOKIE cookie,
  404. LPOLESTR * ppViewType,
  405. long * pViewOptions
  406. )
  407. {
  408. return CDhcpHandler::OnGetResultViewType(pComponent, cookie, ppViewType, pViewOptions);
  409. }
  410. /*!--------------------------------------------------------------------------
  411. CDhcpRootHandler::OnResultSelect
  412. For nodes with task pads, we override the select message to set
  413. the selected node. Nodes with taskpads do not get the MMCN_SHOW
  414. message which is where we normall set the selected node
  415. Author: EricDav
  416. ---------------------------------------------------------------------------*/
  417. HRESULT CDhcpRootHandler::OnResultSelect(ITFSComponent *pComponent, LPDATAOBJECT pDataObject, MMC_COOKIE cookie, LPARAM arg, LPARAM lParam)
  418. {
  419. HRESULT hr = hrOK;
  420. SPITFSNode spRootNode;
  421. CORg(CDhcpHandler::OnResultSelect(pComponent, pDataObject, cookie, arg, lParam));
  422. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  423. UpdateResultMessage(spRootNode);
  424. Error:
  425. return hr;
  426. }
  427. void CDhcpRootHandler::UpdateResultMessage(ITFSNode * pNode)
  428. {
  429. HRESULT hr = hrOK;
  430. int nMessage = ROOT_MESSAGE_NO_SERVERS; // default
  431. int nVisible, nTotal;
  432. int i;
  433. CString strTitle, strBody, strTemp;
  434. if (!m_fViewMessage)
  435. {
  436. ClearMessage(pNode);
  437. }
  438. else
  439. {
  440. CORg(pNode->GetChildCount(&nVisible, &nTotal));
  441. if (nTotal > 0)
  442. {
  443. ClearMessage(pNode);
  444. }
  445. else
  446. {
  447. nMessage = ROOT_MESSAGE_NO_SERVERS;
  448. // now build the text strings
  449. // first entry is the title
  450. strTitle.LoadString(g_uRootMessages[nMessage][0]);
  451. // second entry is the icon
  452. // third ... n entries are the body strings
  453. for (i = 2; g_uRootMessages[nMessage][i] != 0; i++)
  454. {
  455. strTemp.LoadString(g_uRootMessages[nMessage][i]);
  456. strBody += strTemp;
  457. }
  458. ShowMessage(pNode, strTitle, strBody, (IconIdentifier) g_uRootMessages[nMessage][1]);
  459. }
  460. }
  461. Error:
  462. return;
  463. }
  464. /*---------------------------------------------------------------------------
  465. Command handlers
  466. ---------------------------------------------------------------------------*/
  467. /*---------------------------------------------------------------------------
  468. CDhcpRootHandler::OnCreateNewServer
  469. Description
  470. Author: EricDav
  471. ---------------------------------------------------------------------------*/
  472. HRESULT
  473. CDhcpRootHandler::OnCreateNewServer
  474. (
  475. ITFSNode * pNode
  476. )
  477. {
  478. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  479. HRESULT hr = hrOK;
  480. CAddServer dlgAddServer;
  481. BOOL fServerAdded = FALSE;
  482. dlgAddServer.SetServerList(&g_AuthServerList);
  483. if (dlgAddServer.DoModal() == IDOK)
  484. {
  485. if (IsServerInList(pNode, ::UtilCvtWstrToIpAddr(dlgAddServer.m_strIp), dlgAddServer.m_strName))
  486. {
  487. DhcpMessageBox(IDS_ERR_HOST_ALREADY_CONNECTED);
  488. }
  489. else
  490. {
  491. AddServer(dlgAddServer.m_strIp,
  492. dlgAddServer.m_strName,
  493. TRUE);
  494. fServerAdded = TRUE;
  495. }
  496. }
  497. if (fServerAdded)
  498. UpdateResultMessage(pNode);
  499. return hr;
  500. }
  501. /*---------------------------------------------------------------------------
  502. CDhcpRootHandler::OnBrowseServers
  503. Description
  504. Author: EricDav
  505. ---------------------------------------------------------------------------*/
  506. HRESULT
  507. CDhcpRootHandler::OnBrowseServers
  508. (
  509. ITFSNode * pNode
  510. )
  511. {
  512. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  513. HRESULT hr = hrOK;
  514. CServerBrowse dlgBrowse;
  515. BOOL fServerAdded = FALSE;
  516. BEGIN_WAIT_CURSOR;
  517. if (!g_AuthServerList.IsInitialized())
  518. {
  519. hr = g_AuthServerList.Init();
  520. hr = g_AuthServerList.EnumServers();
  521. }
  522. dlgBrowse.SetServerList(&g_AuthServerList);
  523. END_WAIT_CURSOR;
  524. if (dlgBrowse.DoModal() == IDOK)
  525. {
  526. for (int i = 0; i < dlgBrowse.m_astrName.GetSize(); i++)
  527. {
  528. if (IsServerInList(pNode, ::UtilCvtWstrToIpAddr(dlgBrowse.m_astrIp[i]), dlgBrowse.m_astrName[i]))
  529. {
  530. DhcpMessageBox(IDS_ERR_HOST_ALREADY_CONNECTED);
  531. }
  532. else
  533. {
  534. AddServer(dlgBrowse.m_astrIp[i],
  535. dlgBrowse.m_astrName[i],
  536. TRUE);
  537. fServerAdded = TRUE;
  538. }
  539. }
  540. }
  541. if (fServerAdded)
  542. UpdateResultMessage(pNode);
  543. return hr;
  544. }
  545. /*---------------------------------------------------------------------------
  546. CDhcpRootHandler::OnImportOldList
  547. Description
  548. Author: EricDav
  549. ---------------------------------------------------------------------------*/
  550. HRESULT
  551. CDhcpRootHandler::OnImportOldList
  552. (
  553. ITFSNode * pNode
  554. )
  555. {
  556. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  557. DWORD err = LoadOldServerList(pNode);
  558. if (err)
  559. ::DhcpMessageBox(err);
  560. return err;
  561. }
  562. /*---------------------------------------------------------------------------
  563. CDhcpRootHandler::CreateLocalDhcpServer
  564. Description
  565. Author: EricDav
  566. ---------------------------------------------------------------------------*/
  567. void
  568. CDhcpRootHandler::CreateLocalDhcpServer()
  569. {
  570. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  571. CString strName;
  572. // Create the local machine
  573. //
  574. strName.LoadString (IDS_LOOPBACK_IP_ADDR);
  575. AddServer(strName, NULL, TRUE);
  576. }
  577. /*---------------------------------------------------------------------------
  578. CDhcpRootHandler::AddServer
  579. Description
  580. Author: EricDav
  581. ---------------------------------------------------------------------------*/
  582. HRESULT
  583. CDhcpRootHandler::AddServer
  584. (
  585. LPCWSTR pServerIp,
  586. LPCTSTR pServerName,
  587. BOOL bNewServer,
  588. DWORD dwServerOptions,
  589. DWORD dwRefreshInterval,
  590. BOOL bExtension
  591. )
  592. {
  593. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  594. HRESULT hr = hrOK;
  595. CDhcpServer * pDhcpServer = NULL;
  596. SPITFSNodeHandler spHandler;
  597. SPITFSNode spNode, spRootNode;
  598. // Create a handler for the node
  599. try
  600. {
  601. pDhcpServer = new CDhcpServer(m_spTFSCompData, pServerIp);
  602. pDhcpServer->SetName(pServerName);
  603. // Do this so that it will get released correctly
  604. spHandler = pDhcpServer;
  605. }
  606. catch(...)
  607. {
  608. hr = E_OUTOFMEMORY;
  609. }
  610. CORg( hr );
  611. //
  612. // Create the server container information
  613. //
  614. CreateContainerTFSNode(&spNode,
  615. &GUID_DhcpServerNodeType,
  616. pDhcpServer,
  617. pDhcpServer,
  618. m_spNodeMgr);
  619. // Tell the handler to initialize any specific data
  620. pDhcpServer->InitializeNode((ITFSNode *) spNode);
  621. // tell the server to set the name differently in the extension case
  622. if (dwServerOptions & SERVER_OPTION_EXTENSION)
  623. {
  624. m_bMachineAdded = TRUE;
  625. pDhcpServer->SetExtensionName();
  626. }
  627. // Mask out the auto refresh option because we set it next
  628. pDhcpServer->SetServerOptions(dwServerOptions & ~SERVER_OPTION_AUTO_REFRESH);
  629. // if we got a valid refresh interval, then set it.
  630. if (dwRefreshInterval != 0xffffffff)
  631. pDhcpServer->SetAutoRefresh(spNode, dwServerOptions & SERVER_OPTION_AUTO_REFRESH, dwRefreshInterval);
  632. AddServerSortedName(spNode, bNewServer);
  633. if (bNewServer)
  634. {
  635. // need to get our node descriptor
  636. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  637. spRootNode->SetData(TFS_DATA_DIRTY, TRUE);
  638. }
  639. Error:
  640. return hr;
  641. }
  642. /*---------------------------------------------------------------------------
  643. CDhcpRootHandler::IsServerInList
  644. Description
  645. Author: EricDav
  646. ---------------------------------------------------------------------------*/
  647. BOOL
  648. CDhcpRootHandler::IsServerInList
  649. (
  650. ITFSNode * pRootNode,
  651. DHCP_IP_ADDRESS dhcpIpAddressNew,
  652. CString & strName
  653. )
  654. {
  655. HRESULT hr = hrOK;
  656. SPITFSNodeEnum spNodeEnum;
  657. SPITFSNode spCurrentNode;
  658. ULONG nNumReturned = 0;
  659. DHCP_IP_ADDRESS dhcpIpAddressCurrent;
  660. BOOL bFound = FALSE;
  661. CString strCurrentName;
  662. // get the enumerator for this node
  663. pRootNode->GetEnum(&spNodeEnum);
  664. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  665. while (nNumReturned)
  666. {
  667. // walk the list of servers and see if it already exists
  668. CDhcpServer * pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  669. pServer->GetIpAddress(&dhcpIpAddressCurrent);
  670. //if (dhcpIpAddressCurrent == dhcpIpAddressNew)
  671. strCurrentName = pServer->GetName();
  672. if (!strCurrentName.IsEmpty() &&
  673. strName.CompareNoCase(strCurrentName) == 0)
  674. {
  675. bFound = TRUE;
  676. break;
  677. }
  678. // get the next Server in the list
  679. spCurrentNode.Release();
  680. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  681. }
  682. return bFound;
  683. }
  684. /*---------------------------------------------------------------------------
  685. CDhcpRootHandler::OldServerListExists
  686. Description
  687. Author: EricDav
  688. ---------------------------------------------------------------------------*/
  689. BOOL
  690. CDhcpRootHandler::OldServerListExists()
  691. {
  692. RegKey rk;
  693. LONG err;
  694. BOOL bExists = TRUE;
  695. CStringList strList;
  696. err = rk.Open(HKEY_CURRENT_USER, DHCP_REG_USER_KEY_NAME);
  697. if (err != ERROR_SUCCESS)
  698. {
  699. // the key doesn't exist, so there's nothing to import...
  700. // just return ok
  701. bExists = FALSE;
  702. }
  703. err = rk.QueryValue(DHCP_REG_VALUE_HOSTS, strList);
  704. if (err != ERROR_SUCCESS)
  705. bExists = FALSE;
  706. return bExists;
  707. }
  708. /*---------------------------------------------------------------------------
  709. CDhcpRootHandler::LoadOldServerList
  710. Description
  711. Author: EricDav
  712. ---------------------------------------------------------------------------*/
  713. DWORD
  714. CDhcpRootHandler::LoadOldServerList
  715. (
  716. ITFSNode * pNode
  717. )
  718. {
  719. RegKey rk;
  720. CStringList strList ;
  721. CString * pstr ;
  722. POSITION pos ;
  723. LONG err;
  724. BOOL bServerAdded = FALSE;
  725. CString strName;
  726. DHC_HOST_INFO_STRUCT hostInfo;
  727. err = rk.Open(HKEY_CURRENT_USER, DHCP_REG_USER_KEY_NAME);
  728. if (err == ERROR_FILE_NOT_FOUND)
  729. {
  730. // the key doesn't exist, so there's nothing to import...
  731. // just return ok
  732. return ERROR_SUCCESS;
  733. }
  734. else
  735. if (err)
  736. return err;
  737. do
  738. {
  739. if ( err = rk.QueryValue( DHCP_REG_VALUE_HOSTS, strList ) )
  740. {
  741. break ;
  742. }
  743. pos = strList.GetHeadPosition();
  744. if (pos == NULL)
  745. break;
  746. for ( ; pos && (pstr = & strList.GetNext(pos)); /**/ )
  747. {
  748. DHCP_IP_ADDRESS dhcpIpAddress = UtilCvtWstrToIpAddr(*pstr);
  749. err = ::UtilGetHostInfo(dhcpIpAddress, &hostInfo);
  750. if (err == ERROR_SUCCESS)
  751. {
  752. strName = hostInfo._chHostName;
  753. }
  754. // check to see if the server already is in the list
  755. // if not then add
  756. if (!IsServerInList(pNode, dhcpIpAddress, strName))
  757. {
  758. // is this a local machine addr? Convert to real IP
  759. if ((dhcpIpAddress & 0xFF000000) == 127)
  760. {
  761. UtilGetLocalHostAddress(&dhcpIpAddress);
  762. UtilCvtIpAddrToWstr(dhcpIpAddress, pstr);
  763. }
  764. AddServer(*pstr, strName, TRUE, 0, DHCPSNAP_REFRESH_INTERVAL_DEFAULT);
  765. bServerAdded = TRUE;
  766. }
  767. }
  768. }
  769. while ( FALSE ) ;
  770. //
  771. // Set the dirty flag if we added anything to the list
  772. //
  773. if (bServerAdded)
  774. pNode->SetData(TFS_DATA_DIRTY, TRUE);
  775. //
  776. // This isn't really an error -- it just means that we didn't
  777. // find the key name in the list
  778. //
  779. if (err == ERROR_FILE_NOT_FOUND)
  780. {
  781. Trace0("Didn't find old addresses registry key -- starting from scratch");
  782. err = ERROR_SUCCESS;
  783. }
  784. return err ;
  785. }
  786. /*---------------------------------------------------------------------------
  787. CDhcpRootHandler::AddServerSortedIp
  788. Description
  789. Author: EricDav
  790. ---------------------------------------------------------------------------*/
  791. HRESULT
  792. CDhcpRootHandler::AddServerSortedIp
  793. (
  794. ITFSNode * pNewNode,
  795. BOOL bNewServer
  796. )
  797. {
  798. HRESULT hr = hrOK;
  799. SPITFSNodeEnum spNodeEnum;
  800. SPITFSNode spCurrentNode;
  801. SPITFSNode spPrevNode;
  802. SPITFSNode spRootNode;
  803. ULONG nNumReturned = 0;
  804. DHCP_IP_ADDRESS dhcpIpAddressCurrent = 0;
  805. DHCP_IP_ADDRESS dhcpIpAddressTarget;
  806. CDhcpServer * pServer;
  807. // get our target address
  808. pServer = GETHANDLER(CDhcpServer, pNewNode);
  809. pServer->GetIpAddress(&dhcpIpAddressTarget);
  810. // need to get our node descriptor
  811. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  812. // get the enumerator for this node
  813. CORg(spRootNode->GetEnum(&spNodeEnum));
  814. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  815. while (nNumReturned)
  816. {
  817. // walk the list of servers and see if it already exists
  818. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  819. pServer->GetIpAddress(&dhcpIpAddressCurrent);
  820. if (dhcpIpAddressCurrent > dhcpIpAddressTarget)
  821. {
  822. // Found where we need to put it, break out
  823. break;
  824. }
  825. // get the next Server in the list
  826. spPrevNode.Set(spCurrentNode);
  827. spCurrentNode.Release();
  828. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  829. }
  830. // Add the node in based on the PrevNode pointer
  831. if (spPrevNode)
  832. {
  833. if (bNewServer)
  834. {
  835. if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL)
  836. {
  837. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS);
  838. pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID));
  839. }
  840. }
  841. CORg(spRootNode->InsertChild(spPrevNode, pNewNode));
  842. }
  843. else
  844. {
  845. // add to the head
  846. if (m_bExpanded)
  847. {
  848. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_FIRST);
  849. }
  850. CORg(spRootNode->AddChild(pNewNode));
  851. }
  852. Error:
  853. return hr;
  854. }
  855. /*---------------------------------------------------------------------------
  856. CDhcpRootHandler::AddServerSortedName
  857. Description
  858. Author: EricDav
  859. ---------------------------------------------------------------------------*/
  860. HRESULT
  861. CDhcpRootHandler::AddServerSortedName
  862. (
  863. ITFSNode * pNewNode,
  864. BOOL bNewServer
  865. )
  866. {
  867. HRESULT hr = hrOK;
  868. SPITFSNodeEnum spNodeEnum;
  869. SPITFSNode spCurrentNode;
  870. SPITFSNode spPrevNode;
  871. SPITFSNode spRootNode;
  872. ULONG nNumReturned = 0;
  873. CString strTarget, strCurrent;
  874. CDhcpServer * pServer;
  875. // get our target address
  876. pServer = GETHANDLER(CDhcpServer, pNewNode);
  877. strTarget = pServer->GetName();
  878. // need to get our node descriptor
  879. CORg(m_spNodeMgr->GetRootNode(&spRootNode));
  880. // get the enumerator for this node
  881. CORg(spRootNode->GetEnum(&spNodeEnum));
  882. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  883. while (nNumReturned)
  884. {
  885. // walk the list of servers and see if it already exists
  886. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  887. strCurrent = pServer->GetName();
  888. if (strTarget.CompareNoCase(strCurrent) < 0)
  889. {
  890. // Found where we need to put it, break out
  891. break;
  892. }
  893. // get the next Server in the list
  894. spPrevNode.Set(spCurrentNode);
  895. spCurrentNode.Release();
  896. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  897. }
  898. // Add the node in based on the PrevNode pointer
  899. if (spPrevNode)
  900. {
  901. if (bNewServer)
  902. {
  903. if (spPrevNode->GetData(TFS_DATA_SCOPEID) != NULL)
  904. {
  905. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_PREVIOUS);
  906. pNewNode->SetData(TFS_DATA_RELATIVE_SCOPEID, spPrevNode->GetData(TFS_DATA_SCOPEID));
  907. }
  908. }
  909. CORg(spRootNode->InsertChild(spPrevNode, pNewNode));
  910. }
  911. else
  912. {
  913. // add to the head
  914. if (m_bExpanded)
  915. {
  916. pNewNode->SetData(TFS_DATA_RELATIVE_FLAGS, SDI_FIRST);
  917. }
  918. CORg(spRootNode->AddChild(pNewNode));
  919. }
  920. Error:
  921. return hr;
  922. }
  923. /*---------------------------------------------------------------------------
  924. CDhcpRootHandler::CheckMachine
  925. Checks to see if the DHCP server service is running on the local
  926. machine. If it is, it adds it to the list of servers.
  927. Author: EricDav
  928. ---------------------------------------------------------------------------*/
  929. HRESULT
  930. CDhcpRootHandler::CheckMachine
  931. (
  932. ITFSNode * pRootNode,
  933. LPDATAOBJECT pDataObject
  934. )
  935. {
  936. HRESULT hr = hrOK;
  937. // Get the local machine name and check to see if the service
  938. // is installed.
  939. CString strMachineName;
  940. LPTSTR pBuf;
  941. DWORD dwLength = MAX_COMPUTERNAME_LENGTH + 1;
  942. BOOL bExtension = (pDataObject != NULL);
  943. BOOL fInCluster = FALSE;
  944. CString strLocalIp, strLocalName, strIp;
  945. DHC_HOST_INFO_STRUCT hostInfo;
  946. DHCP_IP_ADDRESS dhcpAddress;
  947. if (!bExtension)
  948. {
  949. // just check the local machine
  950. pBuf = strMachineName.GetBuffer(dwLength);
  951. GetComputerName(pBuf, &dwLength);
  952. strMachineName.ReleaseBuffer();
  953. UtilGetLocalHostAddress(&dhcpAddress);
  954. }
  955. else
  956. {
  957. // get the machine name from the data object
  958. strMachineName = Extract<TCHAR>(pDataObject, (CLIPFORMAT) g_cfMachineName, COMPUTERNAME_LEN_MAX);
  959. UtilGetHostAddress(strMachineName, &dhcpAddress);
  960. RemoveOldEntries(pRootNode, dhcpAddress);
  961. }
  962. fInCluster = ::FIsComputerInRunningCluster(strMachineName);
  963. if (fInCluster)
  964. {
  965. if (GetClusterResourceIp(strMachineName, _T("DHCP Service"), strIp) == ERROR_SUCCESS)
  966. {
  967. dhcpAddress = ::UtilCvtWstrToIpAddr(strIp);
  968. }
  969. }
  970. if (fInCluster)
  971. {
  972. // get the resource name for the IP address we just got
  973. UtilGetHostInfo(dhcpAddress, &hostInfo);
  974. strMachineName = hostInfo._chHostName;
  975. }
  976. // check to see if the service is running
  977. BOOL bServiceRunning;
  978. DWORD dwError = ::TFSIsServiceRunning(strMachineName, _T("DHCPServer"), &bServiceRunning);
  979. if (dwError != ERROR_SUCCESS ||
  980. !bServiceRunning)
  981. {
  982. // The following condition could happen to get here:
  983. // o The service is not installed.
  984. // o Couldn't access for some reason.
  985. // o The service isn't running.
  986. // Don't add to the list.
  987. return hrOK;
  988. }
  989. if (!fInCluster)
  990. {
  991. UtilGetHostInfo(dhcpAddress, &hostInfo);
  992. strMachineName = hostInfo._chHostName;
  993. }
  994. // OK. The service is installed, so lets and add it to the list.
  995. if (IsServerInList(pRootNode, dhcpAddress, strMachineName))
  996. return hr;
  997. // looks good, add to list
  998. UtilCvtIpAddrToWstr(dhcpAddress, &strLocalIp);
  999. DWORD dwFlags = SERVER_OPTION_SHOW_ROGUE;
  1000. if (bExtension)
  1001. dwFlags |= SERVER_OPTION_EXTENSION;
  1002. AddServer(strLocalIp, strMachineName, TRUE, dwFlags, DHCPSNAP_REFRESH_INTERVAL_DEFAULT, bExtension);
  1003. m_bMachineAdded = TRUE;
  1004. return hr;
  1005. }
  1006. // when running as an extension, it is possible that we were saved as "local machine"
  1007. // which means that if the saved console file was moved to another machine we need to remove
  1008. // the old entry that was saved
  1009. HRESULT
  1010. CDhcpRootHandler::RemoveOldEntries(ITFSNode * pNode, DHCP_IP_ADDRESS dhcpAddress)
  1011. {
  1012. HRESULT hr = hrOK;
  1013. SPITFSNodeEnum spNodeEnum;
  1014. SPITFSNode spCurrentNode;
  1015. ULONG nNumReturned = 0;
  1016. CDhcpServer * pServer;
  1017. // get the enumerator for this node
  1018. CORg(pNode->GetEnum(&spNodeEnum));
  1019. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  1020. while (nNumReturned)
  1021. {
  1022. // walk the list of servers and see if it already exists
  1023. pServer = GETHANDLER(CDhcpServer, spCurrentNode);
  1024. DHCP_IP_ADDRESS ipaddrCurrent;
  1025. pServer->GetIpAddress(&ipaddrCurrent);
  1026. //if (ipaddrCurrent != dhcpAddress)
  1027. {
  1028. CORg (pNode->RemoveChild(spCurrentNode));
  1029. }
  1030. spCurrentNode.Release();
  1031. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  1032. }
  1033. Error:
  1034. return hr;
  1035. }