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.

2418 lines
60 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. server.cpp
  7. WINS server node information.
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "winssnap.h"
  12. #include "root.h"
  13. #include "Srvlatpp.h"
  14. #include "actreg.h"
  15. #include "reppart.h"
  16. #include "server.h"
  17. #include "svrstats.h"
  18. #include "shlobj.h"
  19. #include "cprogdlg.h"
  20. #include "status.h"
  21. #include "tregkey.h"
  22. #include "verify.h"
  23. #include "pushtrig.h"
  24. #include "ipadddlg.h"
  25. #include <service.h>
  26. #define NB_NAME_MAX_LENGTH 16 // Max length for NetBIOS names
  27. #define LM_NAME_MAX_LENGTH 15 // Maximum length for Lanman-compatible
  28. // NetBIOS Name.
  29. #define DOMAINNAME_LENGTH 255
  30. #define HOSTNAME_LENGTH 16
  31. CNameCache g_NameCache;
  32. int BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
  33. {
  34. int i;
  35. switch (uMsg)
  36. {
  37. case BFFM_INITIALIZED:
  38. SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
  39. break;
  40. }
  41. return 0;
  42. }
  43. /*---------------------------------------------------------------------------
  44. CNameThread
  45. Background thread that resolves names
  46. Author: EricDav
  47. ---------------------------------------------------------------------------*/
  48. CNameThread::CNameThread()
  49. {
  50. m_bAutoDelete = FALSE;
  51. m_hEventHandle = NULL;
  52. m_pServerInfoArray = NULL;
  53. }
  54. CNameThread::~CNameThread()
  55. {
  56. if (m_hEventHandle != NULL)
  57. {
  58. VERIFY(::CloseHandle(m_hEventHandle));
  59. m_hEventHandle = NULL;
  60. }
  61. }
  62. void CNameThread::Init(CServerInfoArray * pServerInfoArray)
  63. {
  64. m_pServerInfoArray = pServerInfoArray;
  65. }
  66. BOOL CNameThread::Start()
  67. {
  68. ASSERT(m_hEventHandle == NULL); // cannot call start twice or reuse the same C++ object
  69. m_hEventHandle = ::CreateEvent(NULL,TRUE /*bManualReset*/,FALSE /*signalled*/, NULL);
  70. if (m_hEventHandle == NULL)
  71. return FALSE;
  72. return CreateThread();
  73. }
  74. void CNameThread::Abort(BOOL fAutoDelete)
  75. {
  76. if (!IsRunning() && fAutoDelete)
  77. {
  78. delete this;
  79. }
  80. else
  81. {
  82. m_bAutoDelete = fAutoDelete;
  83. SetEvent(m_hEventHandle);
  84. }
  85. }
  86. void CNameThread::AbortAndWait()
  87. {
  88. Abort(FALSE);
  89. WaitForSingleObject(m_hThread, INFINITE);
  90. }
  91. BOOL CNameThread::IsRunning()
  92. {
  93. if (WaitForSingleObject(m_hThread, 0) == WAIT_OBJECT_0)
  94. {
  95. return FALSE;
  96. }
  97. else
  98. {
  99. return TRUE;
  100. }
  101. }
  102. int CNameThread::Run()
  103. {
  104. Assert(m_pServerInfoArray);
  105. //
  106. // fill in the host names for each owner in the list
  107. //
  108. UpdateNameCache();
  109. if (FCheckForAbort())
  110. return 29;
  111. for (int i = 0; i < m_pServerInfoArray->GetSize(); i++)
  112. {
  113. if (FCheckForAbort())
  114. break;
  115. DWORD dwIp = m_pServerInfoArray->GetAt(i).m_dwIp;
  116. if (dwIp != 0)
  117. {
  118. CString strName;
  119. if (!GetNameFromCache(dwIp, strName))
  120. {
  121. GetHostName(dwIp, strName);
  122. CNameCacheEntry cacheEntry;
  123. cacheEntry.m_dwIp = dwIp;
  124. cacheEntry.m_strName = strName;
  125. cacheEntry.m_timeLastUpdate.GetCurrentTime();
  126. g_NameCache.Add(cacheEntry);
  127. Trace2("CNameThread::Run - GetHostName for %lx returned %s\n", dwIp, strName);
  128. }
  129. if (FCheckForAbort())
  130. break;
  131. (*m_pServerInfoArray)[i].m_strName = strName;
  132. }
  133. }
  134. return 29; // exit code so I can tell when the thread goes away
  135. }
  136. BOOL CNameThread::FCheckForAbort()
  137. {
  138. if (WaitForSingleObject(m_hEventHandle, 0) == WAIT_OBJECT_0)
  139. {
  140. Trace0("CNameThread::Run - abort detected, exiting...\n");
  141. return TRUE;
  142. }
  143. else
  144. {
  145. return FALSE;
  146. }
  147. }
  148. void CNameThread::UpdateNameCache()
  149. {
  150. CTime time;
  151. time = CTime::GetCurrentTime();
  152. CTimeSpan timespan(0, 1, 0, 0); // 1 hour
  153. for (int i = 0; i < g_NameCache.GetSize(); i++)
  154. {
  155. if (g_NameCache[i].m_timeLastUpdate < (time - timespan))
  156. {
  157. CString strName;
  158. GetHostName(g_NameCache[i].m_dwIp, strName);
  159. g_NameCache[i].m_strName = strName;
  160. if (FCheckForAbort())
  161. break;
  162. }
  163. }
  164. }
  165. BOOL CNameThread::GetNameFromCache(DWORD dwIp, CString & strName)
  166. {
  167. BOOL fFound = FALSE;
  168. for (int i = 0; i < g_NameCache.GetSize(); i++)
  169. {
  170. if (g_NameCache[i].m_dwIp == dwIp)
  171. {
  172. strName = g_NameCache[i].m_strName;
  173. fFound = TRUE;
  174. break;
  175. }
  176. }
  177. return fFound;
  178. }
  179. /*---------------------------------------------------------------------------
  180. Constructor and destructor
  181. Description
  182. Author: EricDav
  183. ---------------------------------------------------------------------------*/
  184. CWinsServerHandler::CWinsServerHandler
  185. (
  186. ITFSComponentData * pComponentData,
  187. LPCWSTR pServerName,
  188. BOOL fConnected,
  189. DWORD dwIp,
  190. DWORD dwFlags,
  191. DWORD dwRefreshInterval
  192. ) : CMTWinsHandler(pComponentData),
  193. m_dwFlags(dwFlags),
  194. m_dwRefreshInterval(dwRefreshInterval),
  195. m_hBinding(NULL)
  196. {
  197. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  198. m_strServerAddress = pServerName;
  199. m_fConnected = fConnected;
  200. m_dwIPAdd = dwIp;
  201. m_hBinding = NULL;
  202. m_bExtension = FALSE;
  203. m_pNameThread = NULL;
  204. strcpy(szIPMon, "");
  205. }
  206. /*---------------------------------------------------------------------------
  207. Constructor and destructor
  208. Description
  209. Author: EricDav
  210. ---------------------------------------------------------------------------*/
  211. CWinsServerHandler::~CWinsServerHandler()
  212. {
  213. HWND hStatsWnd;
  214. // Check to see if this node has a stats sheet up.
  215. hStatsWnd = m_dlgStats.GetSafeHwnd();
  216. if (hStatsWnd != NULL)
  217. {
  218. m_dlgStats.KillRefresherThread();
  219. }
  220. // diconnect from server and make the handle invalid
  221. DisConnectFromWinsServer();
  222. // kill the name query thread if exists
  223. if (m_pNameThread)
  224. {
  225. m_pNameThread->AbortAndWait();
  226. delete m_pNameThread;
  227. }
  228. }
  229. /*!--------------------------------------------------------------------------
  230. CWinsServerHandler::InitializeNode
  231. Initializes node specific data
  232. Author: EricDav
  233. ---------------------------------------------------------------------------*/
  234. HRESULT
  235. CWinsServerHandler::InitializeNode
  236. (
  237. ITFSNode * pNode
  238. )
  239. {
  240. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  241. CString IPAdd;
  242. CString strDisp;
  243. if (m_dwIPAdd != 0)
  244. {
  245. MakeIPAddress(m_dwIPAdd, IPAdd);
  246. strDisp.Format(IDS_SERVER_NAME_FORMAT, m_strServerAddress, IPAdd);
  247. }
  248. else
  249. {
  250. strDisp = m_strServerAddress;
  251. }
  252. SetDisplayName(strDisp);
  253. if (m_fConnected)
  254. {
  255. m_nState = loaded;
  256. }
  257. else
  258. {
  259. m_nState = notLoaded;
  260. }
  261. pNode->SetData(TFS_DATA_IMAGEINDEX, GetImageIndex(FALSE));
  262. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, GetImageIndex(TRUE));
  263. // Make the node immediately visible
  264. pNode->SetVisibilityState(TFS_VIS_SHOW);
  265. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  266. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  267. pNode->SetData(TFS_DATA_TYPE, WINSSNAP_SERVER);
  268. SetColumnStringIDs(&aColumns[WINSSNAP_SERVER][0]);
  269. SetColumnWidths(&aColumnWidths[WINSSNAP_SERVER][0]);
  270. return hrOK;
  271. }
  272. /*---------------------------------------------------------------------------
  273. CWinsServerHandler::OnCreateNodeId2
  274. Returns a unique string for this node
  275. Author: EricDav
  276. ---------------------------------------------------------------------------*/
  277. HRESULT CWinsServerHandler::OnCreateNodeId2(ITFSNode * pNode, CString & strId, DWORD * dwFlags)
  278. {
  279. const GUID * pGuid = pNode->GetNodeType();
  280. CString strGuid;
  281. StringFromGUID2(*pGuid, strGuid.GetBuffer(256), 256);
  282. strGuid.ReleaseBuffer();
  283. strId = m_strServerAddress + strGuid;
  284. return hrOK;
  285. }
  286. /*---------------------------------------------------------------------------
  287. CWinsServerHandler::GetImageIndex
  288. Description
  289. Author: EricDav
  290. ---------------------------------------------------------------------------*/
  291. int
  292. CWinsServerHandler::GetImageIndex(BOOL bOpenImage)
  293. {
  294. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  295. int nIndex = 0;
  296. switch (m_nState)
  297. {
  298. case notLoaded:
  299. nIndex = ICON_IDX_SERVER;
  300. break;
  301. case loaded:
  302. nIndex = ICON_IDX_SERVER_CONNECTED;
  303. m_strConnected.LoadString(IDS_SERVER_CONNECTED);
  304. break;
  305. case unableToLoad:
  306. if (m_dwErr == ERROR_ACCESS_DENIED)
  307. {
  308. nIndex = ICON_IDX_SERVER_NO_ACCESS;
  309. }
  310. else
  311. {
  312. nIndex = ICON_IDX_SERVER_LOST_CONNECTION;
  313. }
  314. m_strConnected.LoadString(IDS_SERVER_NOTCONNECTED);
  315. break;
  316. case loading:
  317. nIndex = ICON_IDX_SERVER_BUSY;
  318. break;
  319. default:
  320. ASSERT(FALSE);
  321. }
  322. return nIndex;
  323. }
  324. /*---------------------------------------------------------------------------
  325. CWinsServerHandler::OnHaveData
  326. Description
  327. Author: EricDav
  328. ---------------------------------------------------------------------------*/
  329. void
  330. CWinsServerHandler::OnHaveData
  331. (
  332. ITFSNode * pParentNode,
  333. ITFSNode * pNewNode
  334. )
  335. {
  336. // expand the node so that child nodes appear correctly
  337. LONG_PTR dwType = pNewNode->GetData(TFS_DATA_TYPE);
  338. switch (dwType)
  339. {
  340. case WINSSNAP_ACTIVE_REGISTRATIONS:
  341. {
  342. CActiveRegistrationsHandler * pActReg = GETHANDLER(CActiveRegistrationsHandler, pNewNode);
  343. pActReg->SetServer(pParentNode);
  344. m_spActiveReg.Set(pNewNode);
  345. }
  346. break;
  347. case WINSSNAP_REPLICATION_PARTNERS:
  348. m_spReplicationPartner.Set(pNewNode);
  349. break;
  350. default:
  351. Assert("Invalid node types passed back to server handler!");
  352. break;
  353. }
  354. pParentNode->AddChild(pNewNode);
  355. // now tell the view to update themselves
  356. ExpandNode(pParentNode, TRUE);
  357. }
  358. /*---------------------------------------------------------------------------
  359. CWinsServerHandler::OnHaveData
  360. Description
  361. Author: EricDav
  362. ---------------------------------------------------------------------------*/
  363. void
  364. CWinsServerHandler::OnHaveData
  365. (
  366. ITFSNode * pParentNode,
  367. LPARAM Data,
  368. LPARAM Type
  369. )
  370. {
  371. // This is how we get non-node data back from the background thread.
  372. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  373. switch (Type)
  374. {
  375. case WINS_QDATA_SERVER_INFO:
  376. {
  377. CServerData * pServerInfo = (CServerData *) Data;
  378. DisConnectFromWinsServer();
  379. m_hBinding = pServerInfo->m_hBinding;
  380. m_dwIPAdd = pServerInfo->m_dwServerIp;
  381. m_strServerAddress = pServerInfo->m_strServerName;
  382. m_cConfig = pServerInfo->m_config;
  383. // update the name string
  384. if (!m_bExtension)
  385. {
  386. SPITFSNode spRoot;
  387. CWinsRootHandler * pRoot;
  388. m_spNodeMgr->GetRootNode(&spRoot);
  389. pRoot = GETHANDLER(CWinsRootHandler, spRoot);
  390. SetDisplay(pParentNode, pRoot->GetShowLongName());
  391. }
  392. delete pServerInfo;
  393. }
  394. break;
  395. }
  396. }
  397. /*---------------------------------------------------------------------------
  398. Overridden base handler functions
  399. ---------------------------------------------------------------------------*/
  400. /*---------------------------------------------------------------------------
  401. CWinsServerHandler::OnAddMenuItems
  402. Description
  403. Author: EricDav
  404. ---------------------------------------------------------------------------*/
  405. STDMETHODIMP
  406. CWinsServerHandler::OnAddMenuItems
  407. (
  408. ITFSNode * pNode,
  409. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  410. LPDATAOBJECT lpDataObject,
  411. DATA_OBJECT_TYPES type,
  412. DWORD dwType,
  413. long * pInsertionAllowed
  414. )
  415. {
  416. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  417. LONG fFlags = 0, fLoadingFlags = 0, f351Flags = 0, fAdminFlags = 0;
  418. HRESULT hr = S_OK;
  419. CString strMenuItem;
  420. BOOL b351 = FALSE;
  421. if ( m_nState != loaded )
  422. {
  423. fFlags |= MF_GRAYED;
  424. }
  425. if ( m_nState == loading)
  426. {
  427. fLoadingFlags = MF_GRAYED;
  428. }
  429. if (!m_cConfig.IsAdmin())
  430. {
  431. fAdminFlags = MF_GRAYED;
  432. }
  433. if (type == CCT_SCOPE)
  434. {
  435. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  436. {
  437. strMenuItem.LoadString(IDS_SHOW_SERVER_STATS);
  438. hr = LoadAndAddMenuItem( pContextMenuCallback,
  439. strMenuItem,
  440. IDS_SHOW_SERVER_STATS,
  441. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  442. fFlags );
  443. ASSERT( SUCCEEDED(hr) );
  444. // separator
  445. hr = LoadAndAddMenuItem( pContextMenuCallback,
  446. strMenuItem,
  447. 0,
  448. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  449. MF_SEPARATOR);
  450. ASSERT( SUCCEEDED(hr) );
  451. // scavenge
  452. strMenuItem.LoadString(IDS_SERVER_SCAVENGE);
  453. hr = LoadAndAddMenuItem( pContextMenuCallback,
  454. strMenuItem,
  455. IDS_SERVER_SCAVENGE,
  456. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  457. fFlags );
  458. ASSERT( SUCCEEDED(hr) );
  459. // check if 351 server is being managed
  460. if ( m_nState == loaded )
  461. b351 = CheckIfNT351Server();
  462. // yes? grey out the consistency check items
  463. if(b351)
  464. f351Flags |= MF_GRAYED;
  465. else
  466. f351Flags &= ~MF_GRAYED;
  467. // only available to admins
  468. strMenuItem.LoadString(IDS_DO_CONSISTENCY_CHECK);
  469. hr = LoadAndAddMenuItem( pContextMenuCallback,
  470. strMenuItem,
  471. IDS_DO_CONSISTENCY_CHECK,
  472. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  473. f351Flags | fFlags | fAdminFlags);
  474. ASSERT( SUCCEEDED(hr) );
  475. // only available to admins
  476. strMenuItem.LoadString(IDS_CHECK_VERSION_CONSISTENCY);
  477. hr = LoadAndAddMenuItem( pContextMenuCallback,
  478. strMenuItem,
  479. IDS_CHECK_VERSION_CONSISTENCY,
  480. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  481. f351Flags | fFlags | fAdminFlags);
  482. ASSERT( SUCCEEDED(hr) );
  483. // separator
  484. hr = LoadAndAddMenuItem( pContextMenuCallback,
  485. strMenuItem,
  486. 0,
  487. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  488. MF_SEPARATOR);
  489. ASSERT( SUCCEEDED(hr) );
  490. // replication triggers
  491. strMenuItem.LoadString(IDS_REP_SEND_PUSH_TRIGGER);
  492. hr = LoadAndAddMenuItem( pContextMenuCallback,
  493. strMenuItem,
  494. IDS_REP_SEND_PUSH_TRIGGER,
  495. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  496. fFlags );
  497. ASSERT( SUCCEEDED(hr) );
  498. strMenuItem.LoadString(IDS_REP_SEND_PULL_TRIGGER);
  499. hr = LoadAndAddMenuItem( pContextMenuCallback,
  500. strMenuItem,
  501. IDS_REP_SEND_PULL_TRIGGER,
  502. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  503. fFlags );
  504. ASSERT( SUCCEEDED(hr) );
  505. // separator
  506. hr = LoadAndAddMenuItem( pContextMenuCallback,
  507. strMenuItem,
  508. 0,
  509. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  510. MF_SEPARATOR);
  511. ASSERT( SUCCEEDED(hr) );
  512. // enable backp and restore database only for local servers
  513. if(IsLocalConnection() && m_nState == loaded)
  514. fFlags &= ~MF_GRAYED;
  515. else
  516. fFlags |= MF_GRAYED;
  517. strMenuItem.LoadString(IDS_SERVER_BACKUP);
  518. hr = LoadAndAddMenuItem( pContextMenuCallback,
  519. strMenuItem,
  520. IDS_SERVER_BACKUP,
  521. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  522. fFlags );
  523. ASSERT( SUCCEEDED(hr) );
  524. // default is to not show this item
  525. fFlags |= MF_GRAYED;
  526. BOOL fServiceRunning = TRUE;
  527. ::TFSIsServiceRunning(m_strServerAddress, _T("WINS"), &fServiceRunning);
  528. if (IsLocalConnection() && m_cConfig.IsAdmin())
  529. {
  530. // the service call can be costly if doing it remotely, so only do it
  531. // when we really need to.
  532. if (!fServiceRunning)
  533. fFlags &= ~MF_GRAYED;
  534. }
  535. strMenuItem.LoadString(IDS_SERVER_RESTORE);
  536. hr = LoadAndAddMenuItem( pContextMenuCallback,
  537. strMenuItem,
  538. IDS_SERVER_RESTORE,
  539. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  540. fFlags );
  541. ASSERT( SUCCEEDED(hr) );
  542. }
  543. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK)
  544. {
  545. // start/stop service menu items
  546. if ( m_nState == notLoaded ||
  547. m_nState == loading)
  548. {
  549. fFlags = MF_GRAYED;
  550. }
  551. else
  552. {
  553. fFlags = 0;
  554. }
  555. DWORD dwServiceStatus, dwErrorCode, dwErr;
  556. dwErr = ::TFSGetServiceStatus(m_strServerAddress, _T("wins"), &dwServiceStatus, &dwErrorCode);
  557. if (dwErr != ERROR_SUCCESS)
  558. fFlags |= MF_GRAYED;
  559. // determining the restart state is the same as the stop flag
  560. LONG lStartFlag = (dwServiceStatus == SERVICE_STOPPED) ? 0 : MF_GRAYED;
  561. LONG lStopFlag = ( (dwServiceStatus == SERVICE_RUNNING) ||
  562. (dwServiceStatus == SERVICE_PAUSED) ) ? 0 : MF_GRAYED;
  563. LONG lPauseFlag = ( (dwServiceStatus == SERVICE_RUNNING) ||
  564. ( (dwServiceStatus != SERVICE_PAUSED) &&
  565. (dwServiceStatus != SERVICE_STOPPED) ) ) ? 0 : MF_GRAYED;
  566. LONG lResumeFlag = (dwServiceStatus == SERVICE_PAUSED) ? 0 : MF_GRAYED;
  567. strMenuItem.LoadString(IDS_SERVER_START_SERVICE);
  568. hr = LoadAndAddMenuItem( pContextMenuCallback,
  569. strMenuItem,
  570. IDS_SERVER_START_SERVICE,
  571. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  572. fFlags | lStartFlag);
  573. strMenuItem.LoadString(IDS_SERVER_STOP_SERVICE);
  574. hr = LoadAndAddMenuItem( pContextMenuCallback,
  575. strMenuItem,
  576. IDS_SERVER_STOP_SERVICE,
  577. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  578. fFlags | lStopFlag);
  579. strMenuItem.LoadString(IDS_SERVER_PAUSE_SERVICE);
  580. hr = LoadAndAddMenuItem( pContextMenuCallback,
  581. strMenuItem,
  582. IDS_SERVER_PAUSE_SERVICE,
  583. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  584. fFlags | lPauseFlag);
  585. strMenuItem.LoadString(IDS_SERVER_RESUME_SERVICE);
  586. hr = LoadAndAddMenuItem( pContextMenuCallback,
  587. strMenuItem,
  588. IDS_SERVER_RESUME_SERVICE,
  589. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  590. fFlags | lResumeFlag);
  591. strMenuItem.LoadString(IDS_SERVER_RESTART_SERVICE);
  592. hr = LoadAndAddMenuItem( pContextMenuCallback,
  593. strMenuItem,
  594. IDS_SERVER_RESTART_SERVICE,
  595. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  596. fFlags | lStopFlag);
  597. /* Don't do this in the snapin, go back to the old command prompt way
  598. strMenuItem.LoadString(IDS_SERVER_COMPACT);
  599. hr = LoadAndAddMenuItem( pContextMenuCallback,
  600. strMenuItem,
  601. IDS_SERVER_COMPACT,
  602. CCM_INSERTIONPOINTID_PRIMARY_TASK,
  603. fFlags );
  604. ASSERT( SUCCEEDED(hr) );
  605. */
  606. }
  607. }
  608. return hr;
  609. }
  610. /*---------------------------------------------------------------------------
  611. CWinsServerHandler::OnCommand
  612. Description
  613. Author: EricDav
  614. ---------------------------------------------------------------------------*/
  615. STDMETHODIMP
  616. CWinsServerHandler::OnCommand
  617. (
  618. ITFSNode * pNode,
  619. long nCommandId,
  620. DATA_OBJECT_TYPES type,
  621. LPDATAOBJECT pDataObject,
  622. DWORD dwType
  623. )
  624. {
  625. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  626. HRESULT hr = S_OK;
  627. switch (nCommandId)
  628. {
  629. case IDS_SHOW_SERVER_STATS:
  630. ShowServerStatDialog(pNode);
  631. break;
  632. case IDS_SERVER_BACKUP:
  633. DoDBBackup(pNode);
  634. break;
  635. case IDS_SERVER_SCAVENGE:
  636. DoDBScavenge(pNode);
  637. break;
  638. case IDS_SERVER_COMPACT:
  639. DoDBCompact(pNode);
  640. break;
  641. case IDS_SERVER_RESTORE:
  642. DoDBRestore(pNode);
  643. break;
  644. case IDS_DO_CONSISTENCY_CHECK:
  645. OnDoConsistencyCheck(pNode);
  646. break;
  647. case IDS_CHECK_VERSION_CONSISTENCY:
  648. OnDoVersionConsistencyCheck(pNode);
  649. break;
  650. case IDS_REP_SEND_PUSH_TRIGGER:
  651. hr = OnSendPushTrigger(pNode);
  652. break;
  653. case IDS_REP_SEND_PULL_TRIGGER:
  654. hr = OnSendPullTrigger(pNode);
  655. break;
  656. case IDS_SERVER_STOP_SERVICE:
  657. hr = OnControlService(pNode, FALSE);
  658. break;
  659. case IDS_SERVER_START_SERVICE:
  660. hr = OnControlService(pNode, TRUE);
  661. break;
  662. case IDS_SERVER_PAUSE_SERVICE:
  663. hr = OnPauseResumeService(pNode, TRUE);
  664. break;
  665. case IDS_SERVER_RESUME_SERVICE:
  666. hr = OnPauseResumeService(pNode, FALSE);
  667. break;
  668. case IDS_SERVER_RESTART_SERVICE:
  669. hr = OnRestartService(pNode);
  670. break;
  671. default:
  672. break;
  673. }
  674. return hr;
  675. }
  676. /*!--------------------------------------------------------------------------
  677. CWinsServerHandler::HasPropertyPages
  678. Implementation of ITFSNodeHandler::HasPropertyPages
  679. NOTE: the root node handler has to over-ride this function to
  680. handle the snapin manager property page (wizard) case!!!
  681. Author: KennT
  682. ---------------------------------------------------------------------------*/
  683. STDMETHODIMP
  684. CWinsServerHandler::HasPropertyPages
  685. (
  686. ITFSNode * pNode,
  687. LPDATAOBJECT pDataObject,
  688. DATA_OBJECT_TYPES type,
  689. DWORD dwType
  690. )
  691. {
  692. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  693. HRESULT hr = hrOK;
  694. if (dwType & TFS_COMPDATA_CREATE)
  695. {
  696. // This is the case where we are asked to bring up property
  697. // pages when the user is adding a new snapin. These calls
  698. // are forwarded to the root node to handle.
  699. hr = hrOK;
  700. Assert(FALSE); // should never get here
  701. }
  702. else
  703. {
  704. // we have property pages in the normal case, but don't put the
  705. // menu up if we are not loaded yet
  706. if ( m_nState != loaded )
  707. {
  708. hr = hrFalse;
  709. }
  710. else
  711. {
  712. hr = hrOK;
  713. }
  714. }
  715. return hr;
  716. }
  717. /*---------------------------------------------------------------------------
  718. CWinsServerHandler::CreatePropertyPages
  719. Description
  720. Author: EricDav
  721. ---------------------------------------------------------------------------*/
  722. STDMETHODIMP
  723. CWinsServerHandler::CreatePropertyPages
  724. (
  725. ITFSNode * pNode,
  726. LPPROPERTYSHEETCALLBACK lpProvider,
  727. LPDATAOBJECT pDataObject,
  728. LONG_PTR handle,
  729. DWORD dwType
  730. )
  731. {
  732. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  733. HRESULT hr = hrOK;
  734. HPROPSHEETPAGE hPage;
  735. SPIComponentData spComponentData;
  736. Assert(pNode->GetData(TFS_DATA_COOKIE) != 0);
  737. //
  738. // Object gets deleted when the page is destroyed
  739. //
  740. m_spNodeMgr->GetComponentData(&spComponentData);
  741. ConnectToWinsServer(pNode);
  742. // to read the values from the registry
  743. DWORD err = m_cConfig.Load(GetBinding());
  744. // unable to read the registry
  745. if (err != ERROR_SUCCESS)
  746. {
  747. ::WinsMessageBox(WIN32_FROM_HRESULT(err));
  748. return hrOK;
  749. }
  750. CServerProperties * pServerProp =
  751. new CServerProperties(pNode, spComponentData, m_spTFSCompData, NULL);
  752. pServerProp->m_pageGeneral.m_uImage = GetImageIndex(FALSE);
  753. pServerProp->SetConfig(&m_cConfig);
  754. Assert(lpProvider != NULL);
  755. return pServerProp->CreateModelessSheet(lpProvider, handle);
  756. }
  757. /*---------------------------------------------------------------------------
  758. CWinsServerHandler::OnPropertyChange
  759. Description
  760. Author: EricDav
  761. ---------------------------------------------------------------------------*/
  762. HRESULT
  763. CWinsServerHandler::OnPropertyChange
  764. (
  765. ITFSNode * pNode,
  766. LPDATAOBJECT pDataobject,
  767. DWORD dwType,
  768. LPARAM arg,
  769. LPARAM lParam
  770. )
  771. {
  772. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  773. CServerProperties * pServerProp
  774. = reinterpret_cast<CServerProperties *>(lParam);
  775. LONG_PTR changeMask = 0;
  776. // tell the property page to do whatever now that we are back on the
  777. // main thread
  778. pServerProp->OnPropertyChange(TRUE, &changeMask);
  779. pServerProp->AcknowledgeNotify();
  780. if (changeMask)
  781. pNode->ChangeNode(changeMask);
  782. return hrOK;
  783. }
  784. /*!--------------------------------------------------------------------------
  785. CWinsServer::Command
  786. Handles commands for the current view
  787. Author: EricDav
  788. ---------------------------------------------------------------------------*/
  789. STDMETHODIMP
  790. CWinsServerHandler::Command
  791. (
  792. ITFSComponent * pComponent,
  793. MMC_COOKIE cookie,
  794. int nCommandID,
  795. LPDATAOBJECT pDataObject
  796. )
  797. {
  798. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  799. HRESULT hr = S_OK;
  800. switch (nCommandID)
  801. {
  802. case MMCC_STANDARD_VIEW_SELECT:
  803. break;
  804. // this may have come from the scope pane handler, so pass it up
  805. default:
  806. hr = HandleScopeCommand(cookie, nCommandID, pDataObject);
  807. break;
  808. }
  809. return hr;
  810. }
  811. /*!--------------------------------------------------------------------------
  812. CWinsServer::AddMenuItems
  813. Over-ride this to add our view menu item
  814. Author: EricDav
  815. ---------------------------------------------------------------------------*/
  816. STDMETHODIMP
  817. CWinsServerHandler::AddMenuItems
  818. (
  819. ITFSComponent * pComponent,
  820. MMC_COOKIE cookie,
  821. LPDATAOBJECT pDataObject,
  822. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  823. long * pInsertionAllowed
  824. )
  825. {
  826. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  827. HRESULT hr = S_OK;
  828. // figure out if we need to pass this to the scope pane menu handler
  829. hr = HandleScopeMenus(cookie, pDataObject, pContextMenuCallback, pInsertionAllowed);
  830. return hr;
  831. }
  832. /*---------------------------------------------------------------------------
  833. Command handlers
  834. ---------------------------------------------------------------------------*/
  835. /*---------------------------------------------------------------------------
  836. CWinsServerHandler::ShowServerStatDialog(ITFSNode* pNode)
  837. Displays the ServerStatistics Window
  838. Author: v-shubk
  839. ---------------------------------------------------------------------------*/
  840. HRESULT
  841. CWinsServerHandler::ShowServerStatDialog(ITFSNode* pNode)
  842. {
  843. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  844. m_dlgStats.SetNode(pNode);
  845. m_dlgStats.SetServer(m_strServerAddress);
  846. CreateNewStatisticsWindow(&m_dlgStats,
  847. ::FindMMCMainWindow(),
  848. IDD_STATS_NARROW);
  849. HRESULT hr = hrOK;
  850. return hr;
  851. }
  852. /*!--------------------------------------------------------------------------
  853. CWinsServerHandler::OnDelete
  854. The base handler calls this when MMC sends a MMCN_DELETE for a
  855. scope pane item. We just call our delete command handler.
  856. Author: EricDav
  857. ---------------------------------------------------------------------------*/
  858. HRESULT
  859. CWinsServerHandler::OnDelete
  860. (
  861. ITFSNode * pNode,
  862. LPARAM arg,
  863. LPARAM lParam
  864. )
  865. {
  866. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  867. HRESULT hr = S_OK;
  868. LONG err = 0 ;
  869. CString strMessage, strTemp;
  870. SPITFSNode spParent;
  871. CWinsStatusHandler *pStat = NULL;
  872. CWinsRootHandler *pRoot = NULL;
  873. strTemp = m_strServerAddress;
  874. AfxFormatString1(strMessage,
  875. IDS_DELETE_SERVER,
  876. m_strServerAddress);
  877. if (AfxMessageBox(strMessage, MB_YESNO) != IDYES)
  878. return NOERROR;
  879. pNode->GetParent(&spParent);
  880. pRoot = GETHANDLER(CWinsRootHandler, spParent);
  881. // remove the node from the status node as well
  882. pStat = GETHANDLER(CWinsStatusHandler, pRoot->m_spStatusNode);
  883. pStat->DeleteNode(pRoot->m_spStatusNode, this);
  884. // remove this node from the list, there's nothing we need to tell
  885. // the server, it's just our local list of servers
  886. spParent->RemoveChild(pNode);
  887. return hr;
  888. }
  889. /*---------------------------------------------------------------------------
  890. CWinsServerHandler::LoadColumns()
  891. Description
  892. Author: v-shubk
  893. ---------------------------------------------------------------------------*/
  894. HRESULT
  895. CWinsServerHandler::LoadColumns(ITFSComponent * pComponent,
  896. MMC_COOKIE cookie,
  897. LPARAM arg,
  898. LPARAM lParam)
  899. {
  900. HRESULT hr = hrOK;
  901. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  902. SPIHeaderCtrl spHeaderCtrl;
  903. pComponent->GetHeaderCtrl(&spHeaderCtrl);
  904. CString str;
  905. int i = 0;
  906. CString strTemp;
  907. strTemp = m_strServerAddress;
  908. while( i< ARRAYLEN(aColumnWidths[1]))
  909. {
  910. if (i == 0)
  911. {
  912. AfxFormatString1(str, IDS_WINSSERVER_NAME, strTemp);
  913. int nTest = spHeaderCtrl->InsertColumn(i,
  914. const_cast<LPTSTR>((LPCWSTR)str),
  915. LVCFMT_LEFT,
  916. aColumnWidths[1][0]);
  917. i++;
  918. }
  919. else
  920. {
  921. str.LoadString(IDS_DESCRIPTION);
  922. int nTest = spHeaderCtrl->InsertColumn(1,
  923. const_cast<LPTSTR>((LPCWSTR)str),
  924. LVCFMT_LEFT,
  925. aColumnWidths[1][1]);
  926. i++;
  927. }
  928. if(aColumns[0][i] == 0)
  929. break;
  930. }
  931. return hrOK;
  932. }
  933. /*!--------------------------------------------------------------------------
  934. CWinsServerHandler::GetStatistics()
  935. Gets the statistics from the server
  936. Author: v-shubk
  937. ---------------------------------------------------------------------------*/
  938. DWORD
  939. CWinsServerHandler::GetStatistics(ITFSNode * pNode, PWINSINTF_RESULTS_T * ppStats)
  940. {
  941. DWORD dwStatus = ERROR_SUCCESS;
  942. CString strName, strIP;
  943. if (ppStats)
  944. *ppStats = NULL;
  945. if (m_dwStatus != ERROR_SUCCESS)
  946. m_dwStatus = ConnectToWinsServer(pNode);
  947. if (m_dwStatus == ERROR_SUCCESS)
  948. {
  949. m_wrResults.WinsStat.NoOfPnrs = 0;
  950. m_wrResults.WinsStat.pRplPnrs = 0;
  951. m_wrResults.NoOfWorkerThds = 1;
  952. #ifdef WINS_CLIENT_APIS
  953. dwStatus = ::WinsStatus(m_hBinding, WINSINTF_E_STAT, &m_wrResults);
  954. #else
  955. dwStatus = ::WinsStatus(WINSINTF_E_STAT, &m_wrResults);
  956. #endif WINS_CLIENT_APIS
  957. if (dwStatus == ERROR_SUCCESS)
  958. {
  959. if (ppStats)
  960. *ppStats = &m_wrResults;
  961. }
  962. }
  963. else
  964. {
  965. dwStatus = m_dwStatus;
  966. }
  967. return dwStatus;
  968. }
  969. /*!--------------------------------------------------------------------------
  970. CWinsServerHandler::ClearStatistics()
  971. Clears the statistics from the server
  972. Author: v-shubk
  973. ---------------------------------------------------------------------------*/
  974. DWORD
  975. CWinsServerHandler::ClearStatistics(ITFSNode *pNode)
  976. {
  977. DWORD dwStatus = ERROR_SUCCESS;
  978. CString strName, strIP;
  979. if (m_dwStatus != ERROR_SUCCESS)
  980. m_dwStatus = ConnectToWinsServer(pNode);
  981. if (m_dwStatus == ERROR_SUCCESS)
  982. {
  983. #ifdef WINS_CLIENT_APIS
  984. dwStatus = ::WinsResetCounters(m_hBinding);
  985. #else
  986. dwStatus = ::WinsResetCounters();
  987. #endif WINS_CLIENT_APIS
  988. }
  989. else
  990. {
  991. dwStatus = m_dwStatus;
  992. }
  993. return dwStatus;
  994. }
  995. /*---------------------------------------------------------------------------
  996. CWinsServerHandler::ConnectToWinsServer()
  997. Connects to the wins server
  998. Author: v-shubk
  999. ---------------------------------------------------------------------------*/
  1000. DWORD
  1001. CWinsServerHandler::ConnectToWinsServer(ITFSNode *pNode)
  1002. {
  1003. HRESULT hr = hrOK;
  1004. CString strServerName, strIP;
  1005. DWORD dwStatus = ERROR_SUCCESS;
  1006. WINSINTF_ADD_T waWinsAddress;
  1007. WINSINTF_BIND_DATA_T wbdBindData;
  1008. // build some information about the server
  1009. strServerName = GetServerAddress();
  1010. DWORD dwIP = GetServerIP();
  1011. MakeIPAddress(dwIP, strIP);
  1012. DisConnectFromWinsServer();
  1013. // now that the server name and ip are valid, call
  1014. // WINSBind function directly.
  1015. do
  1016. {
  1017. char szNetBIOSName[128] = {0};
  1018. // call WinsBind function with the IP address
  1019. wbdBindData.fTcpIp = 1;
  1020. wbdBindData.pPipeName = NULL;
  1021. wbdBindData.pServerAdd = (LPSTR) (LPCTSTR) strIP;
  1022. BEGIN_WAIT_CURSOR
  1023. if ((m_hBinding = ::WinsBind(&wbdBindData)) == NULL)
  1024. {
  1025. m_dwStatus = ::GetLastError();
  1026. break;
  1027. }
  1028. #ifdef WINS_CLIENT_APIS
  1029. m_dwStatus = ::WinsGetNameAndAdd(m_hBinding, &waWinsAddress, (LPBYTE) szNetBIOSName);
  1030. #else
  1031. m_dwStatus = ::WinsGetNameAndAdd(&waWinsAddress, (LPBYTE) szNetBIOSName);
  1032. #endif WINS_CLIENT_APIS
  1033. END_WAIT_CURSOR
  1034. } while (FALSE);
  1035. return m_dwStatus;
  1036. }
  1037. /*---------------------------------------------------------------------------
  1038. CWinsServerHandler::DoDBBackup()
  1039. backs up the database
  1040. Author: v-shubk
  1041. ---------------------------------------------------------------------------*/
  1042. HRESULT
  1043. CWinsServerHandler::DoDBBackup(ITFSNode *pNode)
  1044. {
  1045. HRESULT hr = hrOK;
  1046. DWORD dwStatus = ConnectToWinsServer(pNode);
  1047. CString strBackupPath;
  1048. CString strHelpText;
  1049. strHelpText.LoadString(IDS_SELECT_BACKUP_FOLDER);
  1050. if (GetFolderName(strBackupPath, strHelpText))
  1051. {
  1052. dwStatus = BackupDatabase(strBackupPath);
  1053. if (dwStatus == ERROR_SUCCESS)
  1054. {
  1055. AfxMessageBox(IDS_DB_BACKUP_SUCCESS, MB_ICONINFORMATION | MB_OK);
  1056. // don't update the default path just because they selected a path here
  1057. //if (m_cConfig.m_strBackupPath.CompareNoCase(strBackupPath) != 0)
  1058. //{
  1059. // m_cConfig.m_strBackupPath = strBackupPath;
  1060. // m_cConfig.Store();
  1061. //}
  1062. }
  1063. else
  1064. {
  1065. ::WinsMessageBox(dwStatus, MB_OK);
  1066. }
  1067. }
  1068. return HRESULT_FROM_WIN32(dwStatus);
  1069. }
  1070. /*---------------------------------------------------------------------------
  1071. CWinsServerHandler::BackupDatabase(CString strBackupPath)
  1072. Calls WINS API for backing the database
  1073. Author: v-shubk
  1074. ---------------------------------------------------------------------------*/
  1075. DWORD
  1076. CWinsServerHandler::BackupDatabase(CString strBackupPath)
  1077. {
  1078. BOOL fIncremental = FALSE;
  1079. BOOL fDefaultCharUsed = FALSE;
  1080. DWORD dwStatus = ERROR_SUCCESS;
  1081. char szTemp[MAX_PATH] = {0};
  1082. // INTL$ Should this be ACP or OEMCP?
  1083. WideToMBCS(strBackupPath, szTemp, CP_ACP, 0, &fDefaultCharUsed);
  1084. if (fDefaultCharUsed)
  1085. {
  1086. // could not convert this string... error out
  1087. dwStatus = IDS_ERR_CANT_CONVERT_STRING;
  1088. }
  1089. else
  1090. {
  1091. BEGIN_WAIT_CURSOR
  1092. #ifdef WINS_CLIENT_APIS
  1093. dwStatus = ::WinsBackup(m_hBinding, (unsigned char *)szTemp, (short)fIncremental);
  1094. #else
  1095. dwStatus = ::WinsBackup((unsigned char *)szTemp, (short)fIncremental);
  1096. #endif WINS_CLIENT_APIS
  1097. END_WAIT_CURSOR
  1098. }
  1099. return dwStatus;
  1100. }
  1101. /*---------------------------------------------------------------------------
  1102. CWinsServerHandler::DoDBCompact()
  1103. backs up the database
  1104. Author: v-shubk
  1105. ---------------------------------------------------------------------------*/
  1106. HRESULT
  1107. CWinsServerHandler::DoDBCompact(ITFSNode *pNode)
  1108. {
  1109. HRESULT hr = hrOK;
  1110. // tell the user that we need to stop WINS in order to do this
  1111. if (AfxMessageBox(IDS_WARN_SERVICE_STOP, MB_YESNO) == IDNO)
  1112. return hr;
  1113. CDBCompactProgress dlgCompactProgress;
  1114. dlgCompactProgress.m_dwIpAddress = m_dwIPAdd;
  1115. dlgCompactProgress.m_strServerName = m_strServerAddress;
  1116. dlgCompactProgress.m_hBinding = GetBinding();
  1117. dlgCompactProgress.m_pConfig = &m_cConfig;
  1118. dlgCompactProgress.DoModal();
  1119. // since the service gets restarted, the new binding handle is in the object
  1120. m_hBinding = dlgCompactProgress.m_hBinding;
  1121. return hr;
  1122. }
  1123. /*---------------------------------------------------------------------------
  1124. CWinsServerHandler::DoDBRestore()
  1125. Restores the database
  1126. Author:v-shubk
  1127. ---------------------------------------------------------------------------*/
  1128. HRESULT
  1129. CWinsServerHandler::DoDBRestore(ITFSNode *pNode)
  1130. {
  1131. DWORD dwStatus = 0;
  1132. DWORD err = ERROR_SUCCESS;
  1133. HRESULT hr = hrOK;
  1134. CString strRestorePath;
  1135. CString strHelpText;
  1136. strHelpText.LoadString(IDS_SELECT_RESTORE_FOLDER);
  1137. if (GetFolderName(strRestorePath, strHelpText))
  1138. {
  1139. BOOL fOldBackup = m_cConfig.m_fBackupOnTermination;
  1140. if (!strRestorePath.IsEmpty())
  1141. {
  1142. BEGIN_WAIT_CURSOR
  1143. // need to disable backup on shutdown since we need to shutdown
  1144. // the server to do this and we don't want it to backup and stomp
  1145. // over what we may want to restore.
  1146. if (fOldBackup)
  1147. {
  1148. m_cConfig.m_fBackupOnTermination = FALSE;
  1149. m_cConfig.Store();
  1150. }
  1151. DisConnectFromWinsServer();
  1152. // convert the string from unicode to DBCS for the WINS API
  1153. char szTemp[MAX_PATH * 2] = {0};
  1154. BOOL fDefaultCharUsed = FALSE;
  1155. // INTL$ should this be ACP or OEMCP?
  1156. WideToMBCS(strRestorePath, szTemp, CP_ACP, 0, &fDefaultCharUsed);
  1157. // if there is no code page available for conversion, error out
  1158. if (fDefaultCharUsed)
  1159. {
  1160. dwStatus = IDS_ERR_CANT_CONVERT_STRING;
  1161. }
  1162. else
  1163. {
  1164. dwStatus = ::WinsRestore((LPBYTE) szTemp);
  1165. }
  1166. END_WAIT_CURSOR
  1167. if (dwStatus == ERROR_SUCCESS)
  1168. {
  1169. // re-start the WINS service that was stopped
  1170. CString strServiceDesc;
  1171. strServiceDesc.LoadString(IDS_SERVICE_NAME);
  1172. err = TFSStartServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
  1173. // connect to the server again
  1174. ConnectToWinsServer(pNode);
  1175. // let the user know everything went OK.
  1176. AfxMessageBox(IDS_DB_RESTORE_SUCCESS, MB_ICONINFORMATION | MB_OK);
  1177. }
  1178. else
  1179. {
  1180. ::WinsMessageBox(dwStatus, MB_OK);
  1181. }
  1182. hr = HRESULT_FROM_WIN32(dwStatus);
  1183. // restore the backup on shutdown flag if necessary
  1184. if (fOldBackup)
  1185. {
  1186. m_cConfig.m_fBackupOnTermination = TRUE;
  1187. m_cConfig.Store();
  1188. }
  1189. if (SUCCEEDED(hr))
  1190. {
  1191. // need to refresh the server node because this can only be triggered
  1192. // if the service wasn't running
  1193. if (m_pNameThread)
  1194. {
  1195. m_pNameThread->Abort();
  1196. m_pNameThread = NULL;
  1197. }
  1198. OnRefresh(pNode, NULL, 0, 0, 0);
  1199. }
  1200. }
  1201. }
  1202. return hr;
  1203. }
  1204. /*---------------------------------------------------------------------------
  1205. CWinsServerHandler::OnControlService
  1206. -
  1207. Author: EricDav
  1208. ---------------------------------------------------------------------------*/
  1209. HRESULT
  1210. CWinsServerHandler::OnControlService
  1211. (
  1212. ITFSNode * pNode,
  1213. BOOL fStart
  1214. )
  1215. {
  1216. HRESULT hr = hrOK;
  1217. DWORD err = ERROR_SUCCESS;
  1218. CString strServiceDesc;
  1219. strServiceDesc.LoadString(IDS_SERVICE_NAME);
  1220. if (fStart)
  1221. {
  1222. err = TFSStartServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
  1223. }
  1224. else
  1225. {
  1226. err = TFSStopServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
  1227. }
  1228. if (err == ERROR_SUCCESS)
  1229. {
  1230. // need to refresh the server node because this can only be triggered
  1231. // if the service wasn't running
  1232. if (m_pNameThread)
  1233. {
  1234. m_pNameThread->Abort();
  1235. m_pNameThread = NULL;
  1236. }
  1237. if (!fStart)
  1238. m_fSilent = TRUE;
  1239. OnRefresh(pNode, NULL, 0, 0, 0);
  1240. }
  1241. else
  1242. {
  1243. WinsMessageBox(err);
  1244. hr = HRESULT_FROM_WIN32(err);
  1245. }
  1246. return hr;
  1247. }
  1248. /*---------------------------------------------------------------------------
  1249. CWinsServerHandler::OnPauseResumeService
  1250. -
  1251. Author: EricDav
  1252. ---------------------------------------------------------------------------*/
  1253. HRESULT
  1254. CWinsServerHandler::OnPauseResumeService
  1255. (
  1256. ITFSNode * pNode,
  1257. BOOL fPause
  1258. )
  1259. {
  1260. HRESULT hr = hrOK;
  1261. DWORD err = ERROR_SUCCESS;
  1262. CString strServiceDesc;
  1263. strServiceDesc.LoadString(IDS_SERVICE_NAME);
  1264. if (fPause)
  1265. {
  1266. err = TFSPauseService(m_strServerAddress, _T("wins"), strServiceDesc);
  1267. }
  1268. else
  1269. {
  1270. err = TFSResumeService(m_strServerAddress, _T("wins"), strServiceDesc);
  1271. }
  1272. if (err != ERROR_SUCCESS)
  1273. {
  1274. WinsMessageBox(err);
  1275. hr = HRESULT_FROM_WIN32(err);
  1276. }
  1277. return hr;
  1278. }
  1279. /*---------------------------------------------------------------------------
  1280. CWinsServerHandler::OnRestartService
  1281. -
  1282. Author: EricDav
  1283. ---------------------------------------------------------------------------*/
  1284. HRESULT
  1285. CWinsServerHandler::OnRestartService
  1286. (
  1287. ITFSNode * pNode
  1288. )
  1289. {
  1290. HRESULT hr = hrOK;
  1291. DWORD err = ERROR_SUCCESS;
  1292. CString strServiceDesc;
  1293. strServiceDesc.LoadString(IDS_SERVICE_NAME);
  1294. err = TFSStopServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
  1295. if (err != ERROR_SUCCESS)
  1296. {
  1297. WinsMessageBox(err);
  1298. hr = HRESULT_FROM_WIN32(err);
  1299. }
  1300. if (SUCCEEDED(hr))
  1301. {
  1302. err = TFSStartServiceEx(m_strServerAddress, _T("wins"), _T("WINS Service"), strServiceDesc);
  1303. if (err != ERROR_SUCCESS)
  1304. {
  1305. WinsMessageBox(err);
  1306. hr = HRESULT_FROM_WIN32(err);
  1307. }
  1308. }
  1309. // refresh
  1310. OnRefresh(pNode, NULL, 0, 0, 0);
  1311. return hr;
  1312. }
  1313. /*---------------------------------------------------------------------------
  1314. CWinsServerHandler::UpdateStatistics
  1315. Notification that stats are now available. Update stats for the
  1316. server node and give all subnodes a chance to update.
  1317. Author: EricDav
  1318. ---------------------------------------------------------------------------*/
  1319. DWORD
  1320. CWinsServerHandler::UpdateStatistics
  1321. (
  1322. ITFSNode * pNode
  1323. )
  1324. {
  1325. HRESULT hr = hrOK;
  1326. SPITFSNodeEnum spNodeEnum;
  1327. SPITFSNode spCurrentNode;
  1328. ULONG nNumReturned;
  1329. HWND hStatsWnd;
  1330. BOOL bChangeIcon = FALSE;
  1331. // Check to see if this node has a stats sheet up.
  1332. hStatsWnd = m_dlgStats.GetSafeHwnd();
  1333. if (hStatsWnd != NULL)
  1334. {
  1335. PostMessage(hStatsWnd, WM_NEW_STATS_AVAILABLE, 0, 0);
  1336. }
  1337. return hr;
  1338. }
  1339. /*---------------------------------------------------------------------------
  1340. CWinsServerHandler::DoDBScavenge()
  1341. Scavenges the database
  1342. Author: v-shubk
  1343. ---------------------------------------------------------------------------*/
  1344. HRESULT
  1345. CWinsServerHandler::DoDBScavenge(ITFSNode *pNode)
  1346. {
  1347. HRESULT hr = hrOK;
  1348. DWORD dwStatus;
  1349. if (m_dwStatus != ERROR_SUCCESS)
  1350. {
  1351. dwStatus = ConnectToWinsServer(pNode);
  1352. }
  1353. #ifdef WINS_CLIENT_APIS
  1354. dwStatus = ::WinsDoScavenging(m_hBinding);
  1355. #else
  1356. dwStatus = ::WinsDoScavenging();
  1357. #endif WINS_CLIENT_APIS
  1358. if (dwStatus == ERROR_SUCCESS)
  1359. {
  1360. CString strDisp;
  1361. CString strTemp;
  1362. strTemp.LoadString(IDS_SCAVENGE_COMMAND);
  1363. AfxFormatString1(strDisp, IDS_QUEUED_MESSAGE, strTemp);
  1364. AfxMessageBox(strDisp, MB_ICONINFORMATION|MB_OK);
  1365. BEGIN_WAIT_CURSOR
  1366. // refresh the stats
  1367. m_wrResults.WinsStat.NoOfPnrs = 0;
  1368. m_wrResults.WinsStat.pRplPnrs = 0;
  1369. m_wrResults.NoOfWorkerThds = 1;
  1370. #ifdef WINS_CLIENT_APIS
  1371. dwStatus = ::WinsStatus(m_hBinding, WINSINTF_E_CONFIG, &m_wrResults);
  1372. #else
  1373. dwStatus = ::WinsStatus(WINSINTF_E_CONFIG, &m_wrResults);
  1374. #endif WINS_CLIENT_APIS
  1375. UpdateStatistics(pNode);
  1376. END_WAIT_CURSOR
  1377. }
  1378. else
  1379. {
  1380. ::WinsMessageBox(dwStatus, MB_OK);
  1381. }
  1382. return HRESULT_FROM_WIN32(dwStatus);
  1383. }
  1384. /*---------------------------------------------------------------------------
  1385. CWinsServerHandler::IsValidNetBIOSName
  1386. Determine if the given netbios is valid, and pre-pend
  1387. a double backslash if not already present (and the address
  1388. is otherwise valid).
  1389. ---------------------------------------------------------------------------*/
  1390. BOOL
  1391. CWinsServerHandler::IsValidNetBIOSName
  1392. (
  1393. CString & strAddress,
  1394. BOOL fLanmanCompatible,
  1395. BOOL fWackwack // expand slashes if not present
  1396. )
  1397. {
  1398. TCHAR szWacks[] = _T("\\\\");
  1399. if (strAddress.IsEmpty())
  1400. {
  1401. return FALSE;
  1402. }
  1403. if (strAddress[0] == _T('\\'))
  1404. {
  1405. if (strAddress.GetLength() < 3)
  1406. {
  1407. return FALSE;
  1408. }
  1409. if (strAddress[1] != _T('\\'))
  1410. {
  1411. // One slash only? Not valid
  1412. return FALSE;
  1413. }
  1414. }
  1415. else
  1416. {
  1417. if (fWackwack)
  1418. {
  1419. // Add the backslashes
  1420. strAddress = szWacks + strAddress;
  1421. }
  1422. }
  1423. int nMaxAllowedLength = fLanmanCompatible
  1424. ? LM_NAME_MAX_LENGTH
  1425. : NB_NAME_MAX_LENGTH;
  1426. if (fLanmanCompatible)
  1427. {
  1428. strAddress.MakeUpper();
  1429. }
  1430. return strAddress.GetLength() <= nMaxAllowedLength + 2;
  1431. }
  1432. /*---------------------------------------------------------------------------
  1433. CWinsServerHandler::OnResultRefresh
  1434. Refreshes the data relating to the server
  1435. Author: v-shubk
  1436. ---------------------------------------------------------------------------*/
  1437. HRESULT
  1438. CWinsServerHandler::OnResultRefresh
  1439. (
  1440. ITFSComponent * pComponent,
  1441. LPDATAOBJECT pDataObject,
  1442. MMC_COOKIE cookie,
  1443. LPARAM arg,
  1444. LPARAM lParam
  1445. )
  1446. {
  1447. HRESULT hr = hrOK;
  1448. SPITFSNode spNode;
  1449. CORg (m_spNodeMgr->FindNode(cookie, &spNode));
  1450. if (m_pNameThread)
  1451. {
  1452. m_pNameThread->Abort();
  1453. m_pNameThread = NULL;
  1454. }
  1455. OnRefresh(spNode, pDataObject, 0, arg, lParam);
  1456. Error:
  1457. return hr;
  1458. }
  1459. /*---------------------------------------------------------------------------
  1460. CWinsServerHandler::OnDoConsistencyCheck(ITFSNode *pNode)
  1461. Consisntency Check for WINS
  1462. Author - v-shubk
  1463. ---------------------------------------------------------------------------*/
  1464. HRESULT
  1465. CWinsServerHandler::OnDoConsistencyCheck(ITFSNode *pNode)
  1466. {
  1467. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1468. HRESULT hr = hrOK;
  1469. if(IDYES != AfxMessageBox(IDS_CONSISTENCY_CONFIRM, MB_YESNO))
  1470. return hrFalse;
  1471. WINSINTF_SCV_REQ_T ScvReq;
  1472. ScvReq.Age = 0; // check all the replicas
  1473. ScvReq.fForce = FALSE;
  1474. ScvReq.Opcode_e = WINSINTF_E_SCV_VERIFY;
  1475. #ifdef WINS_CLIENT_APIS
  1476. DWORD dwStatus = ::WinsDoScavengingNew(m_hBinding, &ScvReq);
  1477. #else
  1478. DWORD dwStatus = ::WinsDoScavengingNew(&ScvReq);
  1479. #endif WINS_CLIENT_APIS
  1480. if(dwStatus == ERROR_SUCCESS)
  1481. {
  1482. CString strDisp, strJob;
  1483. strJob.Format(IDS_DO_CONSISTENCY_CHECK_STR);
  1484. AfxFormatString1(strDisp,IDS_QUEUED_MESSAGE, strJob);
  1485. AfxMessageBox(strDisp, MB_OK);
  1486. }
  1487. else
  1488. {
  1489. ::WinsMessageBox(dwStatus, MB_OK);
  1490. }
  1491. return hr;
  1492. }
  1493. /*---------------------------------------------------------------------------
  1494. CWInsServerHandler::OnDoVersionConsistencyCheck(ITFSNode *pNode)
  1495. Performs the version number consistency check
  1496. Author: v-shubk
  1497. ---------------------------------------------------------------------------*/
  1498. HRESULT
  1499. CWinsServerHandler::OnDoVersionConsistencyCheck(ITFSNode *pNode)
  1500. {
  1501. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  1502. HRESULT hr = hrOK;
  1503. if (IDYES != AfxMessageBox(IDS_VERSION_CONSIS_CHECK_WARNING, MB_YESNO))
  1504. return hrOK;
  1505. CCheckVersionProgress dlgCheckVersions;
  1506. dlgCheckVersions.m_dwIpAddress = m_dwIPAdd;
  1507. dlgCheckVersions.m_hBinding = GetBinding();
  1508. dlgCheckVersions.DoModal();
  1509. return hr;
  1510. }
  1511. /*---------------------------------------------------------------------------
  1512. CWinsServerHandler::OnSendPushTrigger()
  1513. Sends Push replication trigger
  1514. ---------------------------------------------------------------------------*/
  1515. HRESULT
  1516. CWinsServerHandler::OnSendPushTrigger(ITFSNode * pNode)
  1517. {
  1518. HRESULT hr = hrOK;
  1519. DWORD err = ERROR_SUCCESS;
  1520. CPushTrig dlgPushTrig;
  1521. CGetTriggerPartner dlgTrigPartner;
  1522. if (dlgTrigPartner.DoModal() != IDOK)
  1523. return hr;
  1524. if (dlgPushTrig.DoModal() != IDOK)
  1525. return hr;
  1526. err = ::SendTrigger(GetBinding(),
  1527. (LONG) dlgTrigPartner.m_dwServerIp,
  1528. TRUE,
  1529. dlgPushTrig.GetPropagate());
  1530. if (err == ERROR_SUCCESS)
  1531. {
  1532. AfxMessageBox(IDS_REPL_QUEUED, MB_ICONINFORMATION);
  1533. }
  1534. else
  1535. {
  1536. WinsMessageBox(err);
  1537. }
  1538. return HRESULT_FROM_WIN32(err);
  1539. }
  1540. /*---------------------------------------------------------------------------
  1541. CWinsServerHandler::OnSendPullTrigger()
  1542. Sends Pull replication trigger
  1543. ---------------------------------------------------------------------------*/
  1544. HRESULT
  1545. CWinsServerHandler::OnSendPullTrigger(ITFSNode * pNode)
  1546. {
  1547. HRESULT hr = hrOK;
  1548. DWORD err = ERROR_SUCCESS;
  1549. CPullTrig dlgPullTrig;
  1550. CGetTriggerPartner dlgTrigPartner;
  1551. if (dlgTrigPartner.DoModal() != IDOK)
  1552. return hr;
  1553. if (dlgPullTrig.DoModal() != IDOK)
  1554. return hr;
  1555. err = ::SendTrigger(GetBinding(),
  1556. (LONG) dlgTrigPartner.m_dwServerIp,
  1557. FALSE,
  1558. FALSE);
  1559. if (err == ERROR_SUCCESS)
  1560. {
  1561. AfxMessageBox(IDS_REPL_QUEUED, MB_ICONINFORMATION);
  1562. }
  1563. else
  1564. {
  1565. ::WinsMessageBox(err);
  1566. }
  1567. return HRESULT_FROM_WIN32(err);
  1568. }
  1569. /*---------------------------------------------------------------------------
  1570. CWinsServerHandler::GetFolderName(CString& strPath)
  1571. Returns the folder name after displaying the
  1572. File Dialog
  1573. ---------------------------------------------------------------------------*/
  1574. BOOL
  1575. CWinsServerHandler::GetFolderName(CString& strPath, CString& strHelpText)
  1576. {
  1577. BOOL fOk = FALSE;
  1578. TCHAR szBuffer[MAX_PATH];
  1579. TCHAR szExpandedPath[MAX_PATH * 2];
  1580. CString strStartingPath = m_cConfig.m_strBackupPath;
  1581. if (strStartingPath.IsEmpty())
  1582. {
  1583. strStartingPath = _T("%SystemDrive%\\");
  1584. }
  1585. ExpandEnvironmentStrings(strStartingPath, szExpandedPath, sizeof(szExpandedPath) / sizeof(TCHAR));
  1586. LPITEMIDLIST pidlPrograms = NULL;
  1587. SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlPrograms);
  1588. BROWSEINFO browseInfo;
  1589. browseInfo.hwndOwner = ::FindMMCMainWindow();
  1590. browseInfo.pidlRoot = pidlPrograms;
  1591. browseInfo.pszDisplayName = szBuffer;
  1592. browseInfo.lpszTitle = strHelpText;
  1593. browseInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS ;
  1594. browseInfo.lpfn = BrowseCallbackProc;
  1595. browseInfo.lParam = (LPARAM) szExpandedPath;
  1596. LPITEMIDLIST pidlBrowse = SHBrowseForFolder(&browseInfo);
  1597. fOk = SHGetPathFromIDList(pidlBrowse, szBuffer);
  1598. CString strBackupPath(szBuffer);
  1599. strPath = strBackupPath;
  1600. LPMALLOC pMalloc = NULL;
  1601. if (pidlPrograms && SUCCEEDED(SHGetMalloc(&pMalloc)))
  1602. {
  1603. if (pMalloc)
  1604. pMalloc->Free(pidlPrograms);
  1605. }
  1606. return fOk;
  1607. }
  1608. /*---------------------------------------------------------------------------
  1609. CWinsServerHandler::SetExtensionName()
  1610. -
  1611. Author: EricDav
  1612. ---------------------------------------------------------------------------*/
  1613. void
  1614. CWinsServerHandler::SetExtensionName()
  1615. {
  1616. SetDisplayName(_T("WINS"));
  1617. m_bExtension = TRUE;
  1618. }
  1619. /*---------------------------------------------------------------------------
  1620. CWinsServerHandler::IsLocalConnection()
  1621. Checks if the local server is being managed
  1622. Author: v-shubk
  1623. ---------------------------------------------------------------------------*/
  1624. BOOL
  1625. CWinsServerHandler::IsLocalConnection()
  1626. {
  1627. // get the server netbios name
  1628. CString strServerName = m_strServerAddress;
  1629. TCHAR lpBuffer[MAX_COMPUTERNAME_LENGTH + 1]; // address of name buffer
  1630. DWORD nSize = MAX_COMPUTERNAME_LENGTH + 1;
  1631. ::GetComputerName(lpBuffer,&nSize);
  1632. CString strCompName(lpBuffer);
  1633. if(strCompName.CompareNoCase(strServerName) == 0)
  1634. return TRUE;
  1635. return FALSE;
  1636. }
  1637. /*---------------------------------------------------------------------------
  1638. CWinsServerHandler:: DeleteWinsServer(CWinsServerObj* pws)
  1639. Calls WinsAPI to delete the server
  1640. Author: v-shubk
  1641. ---------------------------------------------------------------------------*/
  1642. DWORD
  1643. CWinsServerHandler:: DeleteWinsServer
  1644. (
  1645. DWORD dwIpAddress
  1646. )
  1647. {
  1648. DWORD err = ERROR_SUCCESS;
  1649. WINSINTF_ADD_T WinsAdd;
  1650. WinsAdd.Len = 4;
  1651. WinsAdd.Type = 0;
  1652. WinsAdd.IPAdd = dwIpAddress;
  1653. #ifdef WINS_CLIENT_APIS
  1654. err = ::WinsDeleteWins(GetBinding(), &WinsAdd);
  1655. #else
  1656. err = ::WinsDeleteWins(&WinsAdd);
  1657. #endif WINS_CLIENT_APIS
  1658. return err;
  1659. }
  1660. /*---------------------------------------------------------------------------
  1661. CWinsServerHandler::DisConnectFromWinsServer()
  1662. Calls WinsUnbind and makes the binding handle invalid
  1663. ---------------------------------------------------------------------------*/
  1664. void
  1665. CWinsServerHandler::DisConnectFromWinsServer()
  1666. {
  1667. if (m_hBinding)
  1668. {
  1669. CString strIP;
  1670. WINSINTF_BIND_DATA_T wbdBindData;
  1671. DWORD dwIP = GetServerIP();
  1672. MakeIPAddress(dwIP, strIP);
  1673. wbdBindData.fTcpIp = 1;
  1674. wbdBindData.pPipeName = NULL;
  1675. wbdBindData.pServerAdd = (LPSTR) (LPCTSTR) strIP;
  1676. ::WinsUnbind(&wbdBindData, m_hBinding);
  1677. m_hBinding = NULL;
  1678. }
  1679. }
  1680. /*---------------------------------------------------------------------------
  1681. CWinsServerHandler::CheckIfNT351Server()
  1682. Checks if a 351 server is being managed
  1683. ---------------------------------------------------------------------------*/
  1684. BOOL
  1685. CWinsServerHandler::CheckIfNT351Server()
  1686. {
  1687. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1688. DWORD err = ERROR_SUCCESS;
  1689. CString lpstrRoot;
  1690. CString lpstrVersion;
  1691. CString strVersion;
  1692. BOOL f351 = FALSE;
  1693. // don't go to the registry each time -- we have the info in our config object
  1694. // 7/8/98 - EricDav
  1695. /*
  1696. // connect to the registry of the server to find if
  1697. // it's a 351 server
  1698. lpstrRoot = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion");
  1699. lpstrVersion = _T("CurrentVersion");
  1700. RegKey rk;
  1701. err = rk.Open(HKEY_LOCAL_MACHINE, lpstrRoot, KEY_READ, m_strServerAddress);
  1702. // Get the count of items
  1703. if (!err)
  1704. err = rk.QueryValue(lpstrVersion,strVersion) ;
  1705. if(strVersion.CompareNoCase(_T("3.51")) == 0 )
  1706. return TRUE;
  1707. return FALSE;
  1708. */
  1709. if (m_cConfig.m_dwMajorVersion < 4)
  1710. {
  1711. f351 = TRUE;
  1712. }
  1713. return f351;
  1714. }
  1715. /*---------------------------------------------------------------------------
  1716. CWinsServerHandler::SetDisplay()
  1717. Sets the node name to either the host name or FQDN
  1718. ---------------------------------------------------------------------------*/
  1719. void
  1720. CWinsServerHandler::SetDisplay(ITFSNode * pNode, BOOL fFQDN)
  1721. {
  1722. CHAR szHostName[MAX_PATH] = {0};
  1723. CString strIPAdd, strDisplay;
  1724. ::MakeIPAddress(m_dwIPAdd, strIPAdd);
  1725. if (fFQDN)
  1726. {
  1727. // check if the server name was resolved and added
  1728. if (m_dwIPAdd != 0)
  1729. {
  1730. // default is ACP. This should use ACP because winsock uses ACP
  1731. WideToMBCS(m_strServerAddress, szHostName);
  1732. HOSTENT * pHostent = ::gethostbyname((CHAR *) szHostName);
  1733. if (pHostent)
  1734. {
  1735. CString strFQDN;
  1736. MBCSToWide(pHostent->h_name, strFQDN);
  1737. strFQDN.MakeLower();
  1738. strDisplay.Format(IDS_SERVER_NAME_FORMAT, strFQDN, strIPAdd);
  1739. SetDisplayName(strDisplay);
  1740. if (pNode)
  1741. pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA);
  1742. }
  1743. }
  1744. }
  1745. // if not FQDN
  1746. else
  1747. {
  1748. if (m_dwIPAdd != 0)
  1749. {
  1750. strDisplay.Format(IDS_SERVER_NAME_FORMAT, m_strServerAddress, strIPAdd);
  1751. }
  1752. else
  1753. {
  1754. strDisplay = m_strServerAddress;
  1755. }
  1756. SetDisplayName(strDisplay);
  1757. if (pNode)
  1758. pNode->ChangeNode(SCOPE_PANE_CHANGE_ITEM_DATA);
  1759. }
  1760. }
  1761. void
  1762. CWinsServerHandler::GetErrorInfo(CString & strTitle, CString & strBody, IconIdentifier * pIcon)
  1763. {
  1764. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  1765. TCHAR szBuffer[MAX_PATH * 2];
  1766. // build the body text
  1767. LoadMessage(m_dwErr, szBuffer, sizeof(szBuffer) / sizeof(TCHAR));
  1768. AfxFormatString1(strBody, IDS_SERVER_MESSAGE_BODY, szBuffer);
  1769. CString strTemp;
  1770. strTemp.LoadString(IDS_SERVER_MESSAGE_BODY_REFRESH);
  1771. strBody += strTemp;
  1772. // get the title
  1773. strTitle.LoadString(IDS_SERVER_MESSAGE_TITLE);
  1774. // and the icon
  1775. if (pIcon)
  1776. {
  1777. *pIcon = Icon_Error;
  1778. }
  1779. }
  1780. /*---------------------------------------------------------------------------
  1781. Background thread functionality
  1782. ---------------------------------------------------------------------------*/
  1783. /*---------------------------------------------------------------------------
  1784. CWinsServerHandler::OnCreateQuery
  1785. Description
  1786. Author: EricDav
  1787. ---------------------------------------------------------------------------*/
  1788. ITFSQueryObject*
  1789. CWinsServerHandler::OnCreateQuery(ITFSNode * pNode)
  1790. {
  1791. CWinsServerQueryObj* pQuery = NULL;
  1792. HRESULT hr = hrOK;
  1793. COM_PROTECT_TRY
  1794. {
  1795. m_pNameThread = new CNameThread();
  1796. pQuery = new CWinsServerQueryObj(m_spTFSCompData, m_spNodeMgr);
  1797. pQuery->m_strServer = GetServerAddress();
  1798. pQuery->m_dwIPAdd = m_dwIPAdd;
  1799. pQuery->m_pNameThread = m_pNameThread;
  1800. pQuery->m_pServerInfoArray = &m_ServerInfoArray;
  1801. }
  1802. COM_PROTECT_CATCH
  1803. return pQuery;
  1804. }
  1805. /*---------------------------------------------------------------------------
  1806. CWinsServerHandler::OnEventAbort
  1807. Description
  1808. Author: EricDav
  1809. ---------------------------------------------------------------------------*/
  1810. void
  1811. CWinsServerQueryObj::OnEventAbort
  1812. (
  1813. DWORD dwData,
  1814. DWORD dwType
  1815. )
  1816. {
  1817. if (dwType == WINS_QDATA_SERVER_INFO)
  1818. {
  1819. Trace0("CWinsServerHandler::OnEventAbort - deleting version");
  1820. delete ULongToPtr(dwData);
  1821. }
  1822. }
  1823. /*---------------------------------------------------------------------------
  1824. CWinsServerQueryObj::Execute()
  1825. Enumerates everything about a server
  1826. Author: EricDav
  1827. ---------------------------------------------------------------------------*/
  1828. STDMETHODIMP
  1829. CWinsServerQueryObj::Execute()
  1830. {
  1831. HRESULT hr = hrOK;
  1832. WINSINTF_BIND_DATA_T wbdBindData;
  1833. CString strName, strIp;
  1834. DWORD dwStatus = ERROR_SUCCESS;
  1835. DWORD dwIp;
  1836. CServerData * pServerInfo;
  1837. // need to get the server name and IP address if the server is added
  1838. // with Do not connect option
  1839. dwStatus = ::VerifyWinsServer(m_strServer, strName, dwIp);
  1840. if (dwStatus != ERROR_SUCCESS)
  1841. {
  1842. Trace1("CWinsServerQueryObj::Execute() - VerifyWinsServer failed! %d\n", dwStatus);
  1843. // Use the existing information we have to try and connect
  1844. if (m_dwIPAdd)
  1845. {
  1846. // we couldn't resolve the name so just use what we have and try to connect
  1847. strName = m_strServer;
  1848. dwIp = m_dwIPAdd;
  1849. }
  1850. else
  1851. {
  1852. // we don't have an IP for this and we can't resolve the name, so error out
  1853. PostError(dwStatus);
  1854. return hrFalse;
  1855. }
  1856. }
  1857. pServerInfo = new CServerData;
  1858. ::MakeIPAddress(dwIp, strIp);
  1859. pServerInfo->m_strServerName = strName;
  1860. pServerInfo->m_dwServerIp = dwIp;
  1861. pServerInfo->m_hBinding = NULL;
  1862. // get a binding for this server
  1863. wbdBindData.fTcpIp = 1;
  1864. wbdBindData.pPipeName = NULL;
  1865. wbdBindData.pServerAdd = (LPSTR) (LPCTSTR) strIp;
  1866. if ((pServerInfo->m_hBinding = ::WinsBind(&wbdBindData)) == NULL)
  1867. {
  1868. dwStatus = ::GetLastError();
  1869. // send what info we have back to the main thread
  1870. AddToQueue((LPARAM) pServerInfo, WINS_QDATA_SERVER_INFO);
  1871. Trace1("CWinsServerQueryObj::Execute() - WinsBind failed! %d\n", dwStatus);
  1872. PostError(dwStatus);
  1873. return hrFalse;
  1874. }
  1875. // load the configuration object
  1876. //pServerInfo->m_config.SetOwner(strName);
  1877. pServerInfo->m_config.SetOwner(strIp);
  1878. dwStatus = pServerInfo->m_config.Load(pServerInfo->m_hBinding);
  1879. if (dwStatus != ERROR_SUCCESS)
  1880. {
  1881. // send what info we have back to the main thread
  1882. AddToQueue((LPARAM) pServerInfo, WINS_QDATA_SERVER_INFO);
  1883. Trace1("CWinsServerQueryObj::Execute() - Load configuration failed! %d\n", dwStatus);
  1884. PostError(dwStatus);
  1885. return hrFalse;
  1886. }
  1887. // send all of the information back to the main thread here
  1888. handle_t hBinding = pServerInfo->m_hBinding;
  1889. AddToQueue((LPARAM) pServerInfo, WINS_QDATA_SERVER_INFO);
  1890. // build the child nodes
  1891. AddNodes(hBinding);
  1892. return hrFalse;
  1893. }
  1894. /*---------------------------------------------------------------------------
  1895. CWinsServerQueryObj::AddNodes
  1896. Creates the active registrations and replication partners nodes
  1897. Author: EricDav
  1898. ---------------------------------------------------------------------------*/
  1899. void
  1900. CWinsServerQueryObj::AddNodes(handle_t hBinding)
  1901. {
  1902. HRESULT hr = hrOK;
  1903. SPITFSNode spActReg, spRepPart;
  1904. CServerInfoArray * pServerInfoArray;
  1905. //
  1906. // active registrations node
  1907. //
  1908. CActiveRegistrationsHandler *pActRegHand = NULL;
  1909. try
  1910. {
  1911. pActRegHand = new CActiveRegistrationsHandler(m_spTFSCompData);
  1912. }
  1913. catch(...)
  1914. {
  1915. hr = E_OUTOFMEMORY;
  1916. }
  1917. //
  1918. // Create the actreg container information
  1919. //
  1920. CreateContainerTFSNode(&spActReg,
  1921. &GUID_WinsActiveRegNodeType,
  1922. pActRegHand,
  1923. pActRegHand,
  1924. m_spNodeMgr);
  1925. // Tell the handler to initialize any specific data
  1926. pActRegHand->InitializeNode((ITFSNode *) spActReg);
  1927. // load the name type mapping from the registry
  1928. pActRegHand->m_NameTypeMap.SetMachineName(m_strServer);
  1929. pActRegHand->m_NameTypeMap.Load();
  1930. // build the owner mapping
  1931. pActRegHand->m_pServerInfoArray = m_pServerInfoArray;
  1932. pActRegHand->BuildOwnerArray(hBinding);
  1933. // Post this node back to the main thread
  1934. AddToQueue(spActReg);
  1935. pActRegHand->Release();
  1936. //
  1937. // replication partners node
  1938. //
  1939. CReplicationPartnersHandler *pReplicationHand = NULL;
  1940. try
  1941. {
  1942. pReplicationHand = new CReplicationPartnersHandler (m_spTFSCompData);
  1943. }
  1944. catch(...)
  1945. {
  1946. hr = E_OUTOFMEMORY;
  1947. }
  1948. // Create the actreg container information
  1949. CreateContainerTFSNode(&spRepPart,
  1950. &GUID_WinsReplicationNodeType,
  1951. pReplicationHand,
  1952. pReplicationHand,
  1953. m_spNodeMgr);
  1954. // Tell the handler to initialize any specific data
  1955. pReplicationHand->InitializeNode((ITFSNode *) spRepPart);
  1956. // Post this node back to the main thread
  1957. AddToQueue(spRepPart);
  1958. pReplicationHand->Release();
  1959. // kick off the name query thread
  1960. m_pNameThread->Init(m_pServerInfoArray);
  1961. m_pNameThread->Start();
  1962. }