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.

1312 lines
32 KiB

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