Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1356 lines
36 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. server.cpp
  7. IPSecMon machine node handler
  8. FILE HISTORY:
  9. */
  10. #include "stdafx.h"
  11. #include "spddb.h"
  12. #include "apinfo.h"
  13. #include "server.h" // Server definition
  14. #include "servpp.h"
  15. #include "logdatanode.h"
  16. #include "wirelessnode.h"
  17. #include "objplus.h"
  18. #include "ipaddres.h"
  19. CTimerMgr g_TimerMgr;
  20. CHashTable g_HashTable;
  21. extern ULONG RevertDwordBytes(DWORD dw);
  22. /////////////////////////////////////////////////////////////////////
  23. //
  24. // CTimerArray implementation
  25. //
  26. /////////////////////////////////////////////////////////////////////
  27. CTimerMgr::CTimerMgr()
  28. {
  29. }
  30. CTimerMgr::~CTimerMgr()
  31. {
  32. CTimerDesc * pTimerDesc;
  33. for (int i = (int)GetUpperBound(); i >= 0; --i)
  34. {
  35. pTimerDesc = GetAt(i);
  36. if (pTimerDesc->uTimer != 0)
  37. FreeTimer(i);
  38. delete pTimerDesc;
  39. }
  40. }
  41. int
  42. CTimerMgr::AllocateTimer
  43. (
  44. ITFSNode * pNode,
  45. CIpsmServer * pServer,
  46. UINT uTimerValue,
  47. TIMERPROC TimerProc
  48. )
  49. {
  50. int i = 0;
  51. CTimerDesc *pTimerDesc = NULL;
  52. CSingleLock slTimerMgr(&m_csTimerMgr);
  53. // get a lock on the timer mgr for the scope of this
  54. // function.
  55. slTimerMgr.Lock();
  56. // look for an empty slot
  57. for (i = (int)GetUpperBound(); i >= 0; --i)
  58. {
  59. pTimerDesc = GetAt(i);
  60. if (pTimerDesc->uTimer == 0)
  61. break;
  62. }
  63. // did we find one? if not allocate one
  64. if (i < 0)
  65. {
  66. try
  67. {
  68. pTimerDesc = new CTimerDesc;
  69. Add(pTimerDesc);
  70. }
  71. catch(...)
  72. {
  73. //
  74. // Free up memory allocated for the timer
  75. //
  76. if (pTimerDesc != NULL)
  77. {
  78. delete pTimerDesc;
  79. pTimerDesc = NULL;
  80. }
  81. return -1;
  82. }
  83. i = (int)GetUpperBound();
  84. }
  85. pTimerDesc->uTimer = SetTimer(NULL, (UINT) i, uTimerValue, TimerProc);
  86. if (pTimerDesc->uTimer == 0)
  87. return -1;
  88. pTimerDesc->spNode.Set(pNode);
  89. pTimerDesc->pServer = pServer;
  90. pTimerDesc->timerProc = TimerProc;
  91. return i;
  92. }
  93. void
  94. CTimerMgr::FreeTimer
  95. (
  96. UINT_PTR uEventId
  97. )
  98. {
  99. CSingleLock slTimerMgr(&m_csTimerMgr);
  100. // get a lock on the timer mgr for the scope of this
  101. // function.
  102. slTimerMgr.Lock();
  103. CTimerDesc * pTimerDesc;
  104. Assert(uEventId <= (UINT) GetUpperBound());
  105. if (uEventId > (UINT) GetUpperBound())
  106. return;
  107. pTimerDesc = GetAt((int) uEventId);
  108. ::KillTimer(NULL, pTimerDesc->uTimer);
  109. pTimerDesc->spNode.Release();
  110. pTimerDesc->pServer = NULL;
  111. pTimerDesc->uTimer = 0;
  112. }
  113. CTimerDesc *
  114. CTimerMgr::GetTimerDesc
  115. (
  116. UINT_PTR uEventId
  117. )
  118. {
  119. CSingleLock slTimerMgr(&m_csTimerMgr);
  120. // the caller of this function should lock the timer mgr
  121. // while accessing this pointer
  122. CTimerDesc * pTimerDesc;
  123. for (int i = (int)GetUpperBound(); i >= 0; --i)
  124. {
  125. pTimerDesc = GetAt(i);
  126. if (pTimerDesc->uTimer == (UINT) uEventId)
  127. return pTimerDesc;
  128. }
  129. return NULL;
  130. }
  131. void
  132. CTimerMgr::ChangeInterval
  133. (
  134. UINT_PTR uEventId,
  135. UINT uNewInterval
  136. )
  137. {
  138. CSingleLock slTimerMgr(&m_csTimerMgr);
  139. // get a lock on the timer mgr for the scope of this
  140. // function.
  141. slTimerMgr.Lock();
  142. Assert(uEventId <= (UINT) GetUpperBound());
  143. if (uEventId > (UINT) GetUpperBound())
  144. return;
  145. CTimerDesc tempTimerDesc;
  146. CTimerDesc * pTimerDesc;
  147. pTimerDesc = GetAt((int) uEventId);
  148. // kill the old timer
  149. ::KillTimer(NULL, pTimerDesc->uTimer);
  150. // set a new one with the new interval
  151. pTimerDesc->uTimer = ::SetTimer(
  152. NULL,
  153. (UINT) uEventId,
  154. uNewInterval,
  155. pTimerDesc->timerProc);
  156. }
  157. VOID CALLBACK
  158. StatisticsTimerProc
  159. (
  160. HWND hwnd,
  161. UINT uMsg,
  162. UINT_PTR idEvent,
  163. DWORD dwTime
  164. )
  165. {
  166. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  167. CSingleLock slTimerMgr(&g_TimerMgr.m_csTimerMgr);
  168. // get a lock on the timer mgr for the scope of this
  169. // function.
  170. slTimerMgr.Lock();
  171. // on the timer, get the timer descriptor for this event
  172. // Call into the appropriate handler to update the stats.
  173. CTimerDesc * pTimerDesc;
  174. pTimerDesc = g_TimerMgr.GetTimerDesc(idEvent);
  175. if (pTimerDesc != NULL)
  176. {
  177. pTimerDesc->pServer->m_bStatsOnly = TRUE;
  178. pTimerDesc->pServer->OnRefreshStats(
  179. pTimerDesc->spNode,
  180. NULL,
  181. NULL,
  182. 0,
  183. 0);
  184. pTimerDesc->pServer->m_bStatsOnly = FALSE;
  185. }
  186. }
  187. /*---------------------------------------------------------------------------
  188. Class CIpsmServer implementation
  189. ---------------------------------------------------------------------------*/
  190. /*--------------------------------------------------------------------------
  191. Constructor and destructor
  192. Description
  193. Author: NSun
  194. ---------------------------------------------------------------------------*/
  195. CIpsmServer::CIpsmServer
  196. (
  197. ITFSComponentData * pComponentData
  198. ) : CMTIpsmHandler(pComponentData),
  199. m_bStatsOnly(FALSE),
  200. m_StatsTimerId(-1),
  201. m_dwOptions(0)
  202. {
  203. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  204. }
  205. CIpsmServer::~CIpsmServer()
  206. {
  207. /*
  208. if (m_StatsDlg.GetSafeHwnd())
  209. {
  210. WaitForModelessDlgClose(&m_StatsDlg);
  211. }
  212. */
  213. }
  214. /*!--------------------------------------------------------------------------
  215. CIpsmServer::InitializeNode
  216. Initializes node specific data
  217. Author: NSun
  218. ---------------------------------------------------------------------------*/
  219. HRESULT
  220. CIpsmServer::InitializeNode
  221. (
  222. ITFSNode * pNode
  223. )
  224. {
  225. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  226. HRESULT hr = hrOK;
  227. CString strTemp;
  228. HANDLE hsession;
  229. COM_PROTECT_TRY
  230. {
  231. CORg (CreateSpdInfo(&m_spSpdInfo));
  232. CORg (CreateApDbInfo(&m_spApDbInfo));
  233. m_spSpdInfo->SetComputerName((LPTSTR)(LPCTSTR)m_strServerAddress);
  234. m_spApDbInfo->SetComputerName((LPTSTR)(LPCTSTR)m_strServerAddress);
  235. //AfxMessageBox(m_strServerAddress, MB_YESNO); //ERASEME//
  236. #if 0
  237. no need to open a session here as we tried to open a session
  238. when constructing the database.
  239. hr = OpenWZCDbLogSession(
  240. NULL/*(LPTSTR)(LPCTSTR)m_strServerAddress*/,
  241. 0,
  242. &hsession);
  243. if (hr == 0)
  244. {
  245. m_spSpdInfo->SetSession(hsession);
  246. }
  247. #endif //0
  248. BuildDisplayName(&strTemp);
  249. SetDisplayName(strTemp);
  250. // Make the node immediately visible
  251. pNode->SetVisibilityState(TFS_VIS_SHOW);
  252. pNode->SetData(TFS_DATA_COOKIE, (LPARAM) pNode);
  253. pNode->SetData(TFS_DATA_IMAGEINDEX, ICON_IDX_SERVER);
  254. pNode->SetData(TFS_DATA_OPENIMAGEINDEX, ICON_IDX_SERVER);
  255. pNode->SetData(TFS_DATA_USER, (LPARAM) this);
  256. pNode->SetData(TFS_DATA_TYPE, IPSMSNAP_SERVER);
  257. SetColumnStringIDs(&aColumns[IPSMSNAP_SERVER][0]);
  258. SetColumnWidths(&aColumnWidths[IPSMSNAP_SERVER][0]);
  259. // m_StatsDlg.SetData(m_spSpdInfo);
  260. COM_PROTECT_ERROR_LABEL;
  261. }
  262. COM_PROTECT_CATCH
  263. return hr;
  264. }
  265. /*---------------------------------------------------------------------------
  266. CIpsmServer::GetImageIndex
  267. -
  268. Author: NSun
  269. ---------------------------------------------------------------------------*/
  270. int
  271. CIpsmServer::GetImageIndex(BOOL bOpenImage)
  272. {
  273. int nIndex = -1;
  274. switch (m_nState)
  275. {
  276. case notLoaded:
  277. nIndex = ICON_IDX_SERVER;
  278. break;
  279. case loading:
  280. nIndex = ICON_IDX_SERVER_BUSY;
  281. break;
  282. case loaded:
  283. nIndex = ICON_IDX_SERVER_CONNECTED;
  284. break;
  285. case unableToLoad:
  286. nIndex = ICON_IDX_SERVER_LOST_CONNECTION;
  287. break;
  288. default:
  289. ASSERT(FALSE);
  290. }
  291. return nIndex;
  292. }
  293. /*---------------------------------------------------------------------------
  294. CIpsmServer::OnHaveData
  295. When the background thread enumerates nodes to be added to the UI,
  296. we get called back here. We override this to force expansion of the
  297. node so that things show up correctly.
  298. Author: NSun
  299. ---------------------------------------------------------------------------*/
  300. void
  301. CIpsmServer::OnHaveData
  302. (
  303. ITFSNode * pParentNode,
  304. ITFSNode * pNewNode
  305. )
  306. {
  307. CMTIpsmHandler::OnHaveData(pParentNode, pNewNode);
  308. ExpandNode(pParentNode, TRUE);
  309. }
  310. /*---------------------------------------------------------------------------
  311. CIpsmServer::OnHaveData
  312. Description
  313. Author: NSun
  314. ---------------------------------------------------------------------------*/
  315. void
  316. CIpsmServer::OnHaveData
  317. (
  318. ITFSNode * pParentNode,
  319. LPARAM Data,
  320. LPARAM Type
  321. )
  322. {
  323. HRESULT hr = hrOK;
  324. HWND hStatsDlg = NULL;
  325. // This is how we get non-node data back from the background thread.
  326. switch (Type)
  327. {
  328. case IPSECMON_QDATA_REFRESH_STATS:
  329. {
  330. // tell all of the child nodes to clear their status caches
  331. // if any of the nodes is the selected node, then they should
  332. // repaint the window
  333. SPITFSNodeEnum spNodeEnum;
  334. SPITFSNode spCurrentNode;
  335. ULONG nNumReturned;
  336. CORg(pParentNode->GetEnum(&spNodeEnum));
  337. CORg(spNodeEnum->Next(1, &spCurrentNode, &nNumReturned));
  338. while (nNumReturned)
  339. {
  340. LONG_PTR dwDataType = spCurrentNode->GetData(TFS_DATA_TYPE);
  341. switch (dwDataType)
  342. {
  343. case IPFWMON_LOGDATA:
  344. {
  345. CLogDataHandler * pLogDataHandler =
  346. GETHANDLER(CLogDataHandler, spCurrentNode);
  347. pLogDataHandler->UpdateStatus(spCurrentNode);
  348. }
  349. break;
  350. case WLANMON_APDATA:
  351. {
  352. CWirelessHandler * pWirelessHandler =
  353. GETHANDLER(CWirelessHandler, spCurrentNode);
  354. pWirelessHandler->UpdateStatus(spCurrentNode);
  355. }
  356. break;
  357. default:
  358. break;
  359. }
  360. spCurrentNode.Release();
  361. spNodeEnum->Next(1, &spCurrentNode, &nNumReturned);
  362. }
  363. }
  364. break;
  365. case IPSECMON_QDATA_FAILED:
  366. pParentNode->DeleteAllChildren(TRUE);
  367. // in OnChangeState, the sate will be changed to unableToLoad
  368. // and the error will be posted
  369. m_nState = loading;
  370. OnChangeState(pParentNode);
  371. //Also close the statistics window
  372. //hStatsDlg = m_StatsDlg.GetSafeHwnd();
  373. if (hStatsDlg)
  374. {
  375. PostMessage(hStatsDlg, WM_CLOSE, 0, 0);
  376. }
  377. break;
  378. }
  379. COM_PROTECT_ERROR_LABEL;
  380. }
  381. /*---------------------------------------------------------------------------
  382. Overridden base handler functions
  383. ---------------------------------------------------------------------------*/
  384. /*---------------------------------------------------------------------------
  385. CIpsmServer::OnAddMenuItems
  386. Description
  387. Author: NSun
  388. ---------------------------------------------------------------------------*/
  389. STDMETHODIMP
  390. CIpsmServer::OnAddMenuItems
  391. (
  392. ITFSNode * pNode,
  393. LPCONTEXTMENUCALLBACK pContextMenuCallback,
  394. LPDATAOBJECT lpDataObject,
  395. DATA_OBJECT_TYPES type,
  396. DWORD dwType,
  397. long * pInsertionAllowed
  398. )
  399. {
  400. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  401. LONG fFlags = 0;
  402. HRESULT hr = S_OK;
  403. CString strMenuItem;
  404. //TODO handle menu items here
  405. if (m_nState != loaded)
  406. {
  407. fFlags |= MF_GRAYED;
  408. }
  409. if (type == CCT_SCOPE)
  410. {
  411. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  412. {
  413. strMenuItem.LoadString(IDS_MENU_RECONNECT);
  414. hr = LoadAndAddMenuItem( pContextMenuCallback,
  415. strMenuItem,
  416. IDS_MENU_RECONNECT,
  417. CCM_INSERTIONPOINTID_PRIMARY_TOP,
  418. 0
  419. );
  420. ASSERT( SUCCEEDED(hr) );
  421. }
  422. }
  423. return hr;
  424. }
  425. /*---------------------------------------------------------------------------
  426. CIpsmServer::OnCommand
  427. Description
  428. Author: NSun
  429. ---------------------------------------------------------------------------*/
  430. STDMETHODIMP
  431. CIpsmServer::OnCommand
  432. (
  433. ITFSNode * pNode,
  434. long nCommandId,
  435. DATA_OBJECT_TYPES type,
  436. LPDATAOBJECT pDataObject,
  437. DWORD dwType
  438. )
  439. {
  440. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  441. HRESULT hr = S_OK;
  442. switch (nCommandId)
  443. {
  444. case IDS_MENU_RECONNECT:
  445. OnRefresh(pNode, pDataObject, 0, 0, 0);
  446. break;
  447. default:
  448. break;
  449. }
  450. return hr;
  451. }
  452. /*!--------------------------------------------------------------------------
  453. CIpsmServer::HasPropertyPages
  454. Implementation of ITFSNodeHandler::HasPropertyPages
  455. NOTE: the root node handler has to over-ride this function to
  456. handle the snapin manager property page (wizard) case!!!
  457. Author: KennT
  458. ---------------------------------------------------------------------------*/
  459. STDMETHODIMP
  460. CIpsmServer::HasPropertyPages
  461. (
  462. ITFSNode * pNode,
  463. LPDATAOBJECT pDataObject,
  464. DATA_OBJECT_TYPES type,
  465. DWORD dwType
  466. )
  467. {
  468. HRESULT hr = S_FALSE;
  469. #if 0
  470. //TODO: remove #if and #endif to re-enable property pages when ready
  471. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  472. HRESULT hr = hrOK;
  473. if (dwType & TFS_COMPDATA_CREATE)
  474. {
  475. // This is the case where we are asked to bring up property
  476. // pages when the user is adding a new snapin. These calls
  477. // are forwarded to the root node to handle. Only for the root node
  478. hr = hrOK;
  479. Assert(FALSE); // should never get here
  480. }
  481. else
  482. {
  483. // we have property pages in the normal case, but don't put the
  484. // menu up if we are not loaded yet
  485. if ( (m_nState == loaded) ||
  486. (m_nState == unableToLoad) )
  487. {
  488. hr = hrOK;
  489. }
  490. else
  491. {
  492. hr = hrFalse;
  493. }
  494. }
  495. #endif //0
  496. return hr;
  497. }
  498. /*---------------------------------------------------------------------------
  499. CIpsmServer::CreatePropertyPages
  500. Description
  501. Author: NSun
  502. ---------------------------------------------------------------------------*/
  503. STDMETHODIMP
  504. CIpsmServer::CreatePropertyPages
  505. (
  506. ITFSNode * pNode,
  507. LPPROPERTYSHEETCALLBACK lpProvider,
  508. LPDATAOBJECT pDataObject,
  509. LONG_PTR handle,
  510. DWORD dwType
  511. )
  512. {
  513. HRESULT hr = S_FALSE;
  514. return hr;
  515. #if 0
  516. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  517. //
  518. // Create the property page
  519. //
  520. SPIComponentData spComponentData;
  521. m_spNodeMgr->GetComponentData(&spComponentData);
  522. CMachineProperties * pMachineProp = new CMachineProperties(
  523. pNode,
  524. spComponentData,
  525. m_spTFSCompData,
  526. m_spSpdInfo,
  527. NULL,
  528. loaded == m_nState
  529. );
  530. pMachineProp->m_strMachineName = m_strServerAddress;
  531. // fill in the auto refresh info
  532. pMachineProp->m_pageRefresh.m_dwRefreshInterval = GetAutoRefreshInterval();
  533. pMachineProp->m_pageRefresh.m_bAutoRefresh = GetOptions() & IPSMSNAP_OPTIONS_REFRESH ? TRUE : FALSE;
  534. return pMachineProp->CreateModelessSheet(lpProvider, handle);
  535. #endif //0
  536. }
  537. /*---------------------------------------------------------------------------
  538. CIpsmServer::OnPropertyChange
  539. Description
  540. Author: NSun
  541. ---------------------------------------------------------------------------*/
  542. HRESULT
  543. CIpsmServer::OnPropertyChange
  544. (
  545. ITFSNode * pNode,
  546. LPDATAOBJECT pDataobject,
  547. DWORD dwType,
  548. LPARAM arg,
  549. LPARAM lParam
  550. )
  551. {
  552. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  553. CMachineProperties * pMachineProp = reinterpret_cast<CMachineProperties *>(lParam);
  554. LONG_PTR changeMask = 0;
  555. // tell the property page to do whatever now that we are back on the
  556. // main thread
  557. pMachineProp->OnPropertyChange(TRUE, &changeMask);
  558. //Let the main thread know that we are done
  559. pMachineProp->AcknowledgeNotify();
  560. if (changeMask)
  561. pNode->ChangeNode(changeMask);
  562. return hrOK;
  563. }
  564. /*!--------------------------------------------------------------------------
  565. CIpsmServer::OnDelete
  566. The base handler calls this when MMC sends a MMCN_DELETE for a
  567. scope pane item. We just call our delete command handler.
  568. Author: NSun
  569. ---------------------------------------------------------------------------*/
  570. HRESULT
  571. CIpsmServer::OnDelete
  572. (
  573. ITFSNode * pNode,
  574. LPARAM arg,
  575. LPARAM lParam
  576. )
  577. {
  578. return OnDelete(pNode);
  579. }
  580. /*!--------------------------------------------------------------------------
  581. CIpsmServer::OnNotifyExiting
  582. We override this for the server node because we don't want the
  583. icon to change when the thread goes away. Normal behavior is that
  584. the node's icon changes to a wait cursor when the background thread
  585. is running. If we are only doing stats collection, then we
  586. don't want the icon to change.
  587. Author: NSun
  588. ---------------------------------------------------------------------------*/
  589. HRESULT
  590. CIpsmServer::OnNotifyExiting
  591. (
  592. LPARAM lParam
  593. )
  594. {
  595. CIpsmServerQueryObj * pQuery = (CIpsmServerQueryObj *) lParam;
  596. if (!pQuery->m_bStatsOnly)
  597. OnChangeState(m_spNode);
  598. ReleaseThreadHandler();
  599. Unlock();
  600. return hrOK;
  601. }
  602. /*---------------------------------------------------------------------------
  603. Command handlers
  604. ---------------------------------------------------------------------------*/
  605. /*!--------------------------------------------------------------------------
  606. CIpsmServer::OnRefresh
  607. Default implementation for the refresh functionality
  608. Author: NSun
  609. ---------------------------------------------------------------------------*/
  610. HRESULT
  611. CIpsmServer::OnRefresh
  612. (
  613. ITFSNode * pNode,
  614. LPDATAOBJECT pDataObject,
  615. DWORD dwType,
  616. LPARAM arg,
  617. LPARAM param
  618. )
  619. {
  620. HRESULT hr = S_OK;
  621. m_spSpdInfo->Destroy();
  622. m_spApDbInfo->Destroy();
  623. hr = CMTHandler::OnRefresh(pNode, pDataObject, dwType, arg, param);
  624. /*
  625. HWND hStatsDlg = m_StatsDlg.GetSafeHwnd();
  626. if (hStatsDlg)
  627. {
  628. PostMessage(hStatsDlg, WM_UPDATE_STATS, 0, 0);
  629. }
  630. */
  631. return hr;
  632. }
  633. /*!--------------------------------------------------------------------------
  634. CIpsmServer::OnRefreshStats
  635. Default implementation for the Stats refresh functionality
  636. Author: NSun
  637. ---------------------------------------------------------------------------*/
  638. HRESULT
  639. CIpsmServer::OnRefreshStats
  640. (
  641. ITFSNode * pNode,
  642. LPDATAOBJECT pDataObject,
  643. DWORD dwType,
  644. LPARAM arg,
  645. LPARAM param
  646. )
  647. {
  648. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  649. HRESULT hr = hrOK;
  650. SPITFSNode spNode;
  651. SPITFSNodeHandler spHandler;
  652. ITFSQueryObject * pQuery = NULL;
  653. if (m_bExpanded == FALSE)
  654. {
  655. // we cannot get statistics if the node hasn't been expanded yet
  656. return hr;
  657. }
  658. // only do stats refresh if the server was loaded correctly.
  659. if (m_nState != loaded)
  660. return hr;
  661. BOOL bLocked = IsLocked();
  662. if (bLocked)
  663. {
  664. // cannot refresh stats if this node is locked
  665. return hr;
  666. }
  667. Lock();
  668. //OnChangeState(pNode);
  669. pQuery = OnCreateQuery(pNode);
  670. Assert(pQuery);
  671. // notify the UI to change icon, if needed
  672. //Verify(SUCCEEDED(pComponentData->ChangeNode(this, SCOPE_PANE_CHANGE_ITEM_ICON)));
  673. Verify(StartBackgroundThread(pNode, m_spTFSCompData->GetHiddenWnd(), pQuery));
  674. pQuery->Release();
  675. return hrOK;
  676. }
  677. /*---------------------------------------------------------------------------
  678. CIpsmServer::OnDelete()
  679. Description
  680. Author: NSun
  681. ---------------------------------------------------------------------------*/
  682. HRESULT
  683. CIpsmServer::OnDelete(ITFSNode * pNode)
  684. {
  685. AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
  686. HRESULT hr = S_OK;
  687. CString strMessage;
  688. AfxFormatString1(strMessage, IDS_WARN_SERVER_DELETE, m_strServerAddress);
  689. if (AfxMessageBox(strMessage, MB_YESNO) == IDYES)
  690. {
  691. // remove this node from the list, there's nothing we need to tell
  692. // the server, it's just our local list of servers
  693. SPITFSNode spParent;
  694. pNode->GetParent(&spParent);
  695. spParent->RemoveChild(pNode);
  696. }
  697. return hr;
  698. }
  699. /*---------------------------------------------------------------------------
  700. Server manipulation functions
  701. ---------------------------------------------------------------------------*/
  702. /*---------------------------------------------------------------------------
  703. CIpsmServer::BuildDisplayName
  704. Builds the string that goes in the UI for this server
  705. Author: NSun
  706. ---------------------------------------------------------------------------*/
  707. HRESULT
  708. CIpsmServer::BuildDisplayName
  709. (
  710. CString * pstrDisplayName
  711. )
  712. {
  713. if (pstrDisplayName)
  714. {
  715. *pstrDisplayName = GetName();
  716. }
  717. return hrOK;
  718. }
  719. /*---------------------------------------------------------------------------
  720. CIpsmServer::SetAutoRefresh
  721. Description
  722. Author: NSun
  723. ---------------------------------------------------------------------------*/
  724. HRESULT
  725. CIpsmServer::SetAutoRefresh
  726. (
  727. ITFSNode * pNode,
  728. BOOL bOn,
  729. DWORD dwRefreshInterval
  730. )
  731. {
  732. BOOL bCurrentAutoRefresh = IsAutoRefreshEnabled();
  733. if (bCurrentAutoRefresh &&
  734. !bOn)
  735. {
  736. // turning off the timer
  737. g_TimerMgr.FreeTimer(m_StatsTimerId);
  738. }
  739. else
  740. if (!bCurrentAutoRefresh &&
  741. bOn)
  742. {
  743. // gotta turn on the timer
  744. m_StatsTimerId = g_TimerMgr.AllocateTimer(pNode, this, dwRefreshInterval, StatisticsTimerProc);
  745. }
  746. else
  747. if (bOn &&
  748. m_dwRefreshInterval != dwRefreshInterval)
  749. {
  750. // time to change the timer
  751. g_TimerMgr.ChangeInterval(m_StatsTimerId, dwRefreshInterval);
  752. }
  753. if (bOn)
  754. m_dwOptions |= IPSMSNAP_OPTIONS_REFRESH;
  755. else
  756. m_dwOptions &= ~IPSMSNAP_OPTIONS_REFRESH;
  757. m_dwRefreshInterval = dwRefreshInterval;
  758. return hrOK;
  759. }
  760. /*---------------------------------------------------------------------------
  761. CIpsmServer::SetDnsResolve
  762. Description
  763. Author: Briansw
  764. ---------------------------------------------------------------------------*/
  765. HRESULT
  766. CIpsmServer::SetDnsResolve
  767. (
  768. ITFSNode * pNode,
  769. BOOL bEnable
  770. )
  771. {
  772. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  773. if (bEnable)
  774. m_dwOptions |= IPSMSNAP_OPTIONS_DNS;
  775. else
  776. m_dwOptions &= ~IPSMSNAP_OPTIONS_DNS;
  777. g_HashTable.SetDnsResolve(bEnable);
  778. return hrOK;
  779. }
  780. /*---------------------------------------------------------------------------
  781. CIpsmServer::SetAutoRefresh
  782. Description
  783. Author: NSun
  784. ---------------------------------------------------------------------------*/
  785. void
  786. CIpsmServer::SetExtensionName()
  787. {
  788. CString strName;
  789. strName.LoadString(IDS_IPSECMON);
  790. SetDisplayName(strName);
  791. }
  792. /*!--------------------------------------------------------------------------
  793. CIpsmServer::UpdateStandardVerbs
  794. Updates the standard verbs depending upon the state of the node
  795. Author: NSun
  796. ---------------------------------------------------------------------------*/
  797. void
  798. CIpsmServer::UpdateConsoleVerbs
  799. (
  800. IConsoleVerb * pConsoleVerb,
  801. LONG_PTR dwNodeType,
  802. BOOL bMultiSelect
  803. )
  804. {
  805. BOOL bStates[ARRAYLEN(g_ConsoleVerbs)];
  806. MMC_BUTTON_STATE * ButtonState;
  807. int i;
  808. if (bMultiSelect)
  809. {
  810. ButtonState = g_ConsoleVerbStatesMultiSel[dwNodeType];
  811. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  812. }
  813. else
  814. {
  815. ButtonState = g_ConsoleVerbStates[dwNodeType];
  816. switch (m_nState)
  817. {
  818. case loaded:
  819. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = TRUE);
  820. break;
  821. case notLoaded:
  822. case loading:
  823. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  824. break;
  825. case unableToLoad:
  826. for (i = 0; i < ARRAYLEN(g_ConsoleVerbs); bStates[i++] = FALSE);
  827. bStates[MMC_VERB_REFRESH & 0x000F] = TRUE;
  828. bStates[MMC_VERB_DELETE & 0x000F] = TRUE;
  829. bStates[MMC_VERB_PROPERTIES & 0x000F] = TRUE;
  830. break;
  831. }
  832. }
  833. EnableVerbs(pConsoleVerb, ButtonState, bStates);
  834. }
  835. /*---------------------------------------------------------------------------
  836. Background thread functionality
  837. ---------------------------------------------------------------------------*/
  838. /*---------------------------------------------------------------------------
  839. CIpsmServer::OnCreateQuery
  840. Description
  841. Author: NSun
  842. ---------------------------------------------------------------------------*/
  843. ITFSQueryObject*
  844. CIpsmServer::OnCreateQuery(ITFSNode * pNode)
  845. {
  846. CIpsmServerQueryObj* pQuery =
  847. new CIpsmServerQueryObj(m_spTFSCompData, m_spNodeMgr);
  848. pQuery->m_strServer = GetName();
  849. pQuery->m_spSpdInfo.Set(m_spSpdInfo);
  850. pQuery->m_spApDbInfo.Set(m_spApDbInfo);
  851. pQuery->m_bStatsOnly = m_bStatsOnly;
  852. return pQuery;
  853. }
  854. /*---------------------------------------------------------------------------
  855. CIpsmServerQueryObj::Execute()
  856. Description
  857. Author: NSun
  858. ---------------------------------------------------------------------------*/
  859. STDMETHODIMP
  860. CIpsmServerQueryObj::Execute()
  861. {
  862. HRESULT hr = S_OK;
  863. DWORD dwActive=m_spSpdInfo->GetActiveInfo();
  864. DWORD dwInit=m_spSpdInfo->GetInitInfo();
  865. // DWORD dwApActive=m_spApDbInfo->GetActiveInfo();
  866. // DWORD dwApInit=m_spApDbInfo->GetInitInfo();
  867. DWORD dwNew = 0;
  868. DWORD dwTotal = 0;
  869. int i;
  870. //Query the data from SPD
  871. //switch(dwActive) {
  872. /*case MON_FILTER:
  873. CORg(m_spSpdInfo->EnumFWFilters());
  874. break;
  875. */
  876. //case MON_LOG_DATA:
  877. CORg(m_spSpdInfo->EnumLogData(&dwNew, &dwTotal));
  878. CORg(m_spApDbInfo->EnumApData());
  879. // break;
  880. //default:
  881. // Initial load. Ping server to see if its up
  882. //CORg(m_spSpdInfo->LoadStatistics());
  883. // break;
  884. //}
  885. if (m_bStatsOnly)
  886. {
  887. // we post this message esentially to get back on the main thread
  888. // so that we can update the UI
  889. AddToQueue(NULL, IPSECMON_QDATA_REFRESH_STATS);
  890. return hrFalse;
  891. }
  892. {
  893. //Add the access point node
  894. SPITFSNode spWirelessNode;
  895. CWirelessHandler *pWirelessHandler = new
  896. CWirelessHandler(m_spTFSCompData);
  897. CreateContainerTFSNode( &spWirelessNode,
  898. &GUID_IpfmWirelessNodeType,
  899. pWirelessHandler,
  900. pWirelessHandler,
  901. m_spNodeMgr);
  902. pWirelessHandler->InitApData(m_spApDbInfo);
  903. pWirelessHandler->InitializeNode(spWirelessNode);
  904. AddToQueue(spWirelessNode);
  905. pWirelessHandler->Release();
  906. //pNode->AddChild(spWirelessNode);
  907. // add the wireless log node
  908. SPITFSNode spLogDataNode;
  909. CLogDataHandler * pLogDataHandler = new
  910. CLogDataHandler(m_spTFSCompData);
  911. CreateContainerTFSNode(&spLogDataNode,
  912. &GUID_IpfmLogDataNodeType,
  913. pLogDataHandler,
  914. pLogDataHandler,
  915. m_spNodeMgr);
  916. pLogDataHandler->InitData(m_spSpdInfo);
  917. pLogDataHandler->InitializeNode(spLogDataNode);
  918. AddToQueue(spLogDataNode);
  919. pLogDataHandler->Release();
  920. //pNode->AddChild(spLogDataNode);
  921. }
  922. COM_PROTECT_ERROR_LABEL;
  923. if (FAILED(hr))
  924. {
  925. PostError(WIN32_FROM_HRESULT(hr));
  926. if (m_bStatsOnly)
  927. {
  928. //If we are doing auto-refresh, tell the main thread
  929. //that the query failed
  930. AddToQueue(NULL, IPSECMON_QDATA_FAILED);
  931. }
  932. }
  933. return hrFalse;
  934. }
  935. CHashTable::CHashTable()
  936. {
  937. DWORD i;
  938. m_bDnsResolveActive=FALSE;
  939. m_bThreadRunning=FALSE;
  940. for (i=0; i < TOTAL_TABLE_SIZE; i++) {
  941. InitializeListHead(&HashTable[i]);
  942. }
  943. }
  944. DWORD
  945. CHashTable::AddPendingObject(in_addr IpAddr)
  946. {
  947. HashEntry *newEntry=new HashEntry;
  948. CSingleLock slHashLock(&m_csHashLock);
  949. slHashLock.Lock();
  950. if (newEntry == NULL) {
  951. return ERROR_OUTOFMEMORY;
  952. }
  953. newEntry->IpAddr=IpAddr;
  954. InsertHeadList(&HashTable[PENDING_INDEX],&newEntry->Linkage);
  955. return ERROR_SUCCESS;
  956. }
  957. DWORD
  958. CHashTable::AddObject(HashEntry *pHE)
  959. {
  960. DWORD Key=HashData(pHE->IpAddr);
  961. CSingleLock slHashLock(&m_csHashLock);
  962. slHashLock.Lock();
  963. InsertHeadList(&HashTable[Key],&pHE->Linkage);
  964. return ERROR_SUCCESS;
  965. }
  966. DWORD
  967. CHashTable::GetObject(HashEntry **ppHashEntry,in_addr IpAddr)
  968. {
  969. DWORD Key=HashData(IpAddr);
  970. HashEntry *pHE;
  971. PLIST_ENTRY pEntry;
  972. DWORD dwErr;
  973. pHE=NULL;
  974. CSingleLock slHashLock(&m_csHashLock);
  975. slHashLock.Lock();
  976. if (!m_bDnsResolveActive) {
  977. return ERROR_NOT_READY;
  978. }
  979. // Start resolver thread
  980. if (!m_bThreadRunning) {
  981. AfxBeginThread((AFX_THREADPROC)HashResolverCallback,
  982. NULL);
  983. m_bThreadRunning=TRUE;
  984. }
  985. for ( pEntry = HashTable[Key].Flink;
  986. pEntry != &HashTable[Key];
  987. pEntry = pEntry->Flink) {
  988. pHE = CONTAINING_RECORD(pEntry,
  989. HashEntry,
  990. Linkage);
  991. if (memcmp(&pHE->IpAddr,&IpAddr,sizeof(in_addr)) == 0) {
  992. *ppHashEntry = pHE;
  993. return ERROR_SUCCESS;
  994. }
  995. }
  996. dwErr=AddPendingObject(IpAddr);
  997. return ERROR_INVALID_PARAMETER;
  998. }
  999. DWORD
  1000. CHashTable::FlushTable()
  1001. {
  1002. DWORD i;
  1003. PLIST_ENTRY pEntry,pNextEntry;
  1004. HashEntry *pHE;
  1005. CSingleLock slHashLock(&m_csHashLock);
  1006. slHashLock.Lock();
  1007. for (i=0; i < TOTAL_TABLE_SIZE; i++) {
  1008. pEntry = HashTable[i].Flink;
  1009. while ( pEntry != &HashTable[i]) {
  1010. pHE = CONTAINING_RECORD(pEntry,
  1011. HashEntry,
  1012. Linkage);
  1013. pNextEntry=pEntry->Flink;
  1014. delete pHE;
  1015. pEntry=pNextEntry;
  1016. }
  1017. InitializeListHead(&HashTable[i]);
  1018. }
  1019. return ERROR_SUCCESS;
  1020. }
  1021. CHashTable::~CHashTable()
  1022. {
  1023. DWORD i;
  1024. PLIST_ENTRY pEntry,pNextEntry;
  1025. HashEntry *pHE;
  1026. m_bDnsResolveActive=FALSE;
  1027. while(m_bThreadRunning) {
  1028. Sleep(10);
  1029. }
  1030. CSingleLock slHashLock(&m_csHashLock);
  1031. slHashLock.Lock();
  1032. for (i=0; i < TOTAL_TABLE_SIZE; i++) {
  1033. pEntry = HashTable[i].Flink;
  1034. while ( pEntry != &HashTable[i]) {
  1035. pHE = CONTAINING_RECORD(pEntry,
  1036. HashEntry,
  1037. Linkage);
  1038. pNextEntry=pEntry->Flink;
  1039. delete pHE;
  1040. pEntry=pNextEntry;
  1041. }
  1042. }
  1043. }
  1044. HRESULT
  1045. CHashTable::SetDnsResolve(BOOL bEnable)
  1046. {
  1047. CSingleLock slHashLock(&m_csHashLock);
  1048. slHashLock.Lock();
  1049. if (m_bDnsResolveActive != bEnable) {
  1050. m_bDnsResolveActive = bEnable;
  1051. FlushTable();
  1052. }
  1053. return hrOK;
  1054. }
  1055. DWORD
  1056. CHashTable::HashData(in_addr IpAddr)
  1057. {
  1058. int i;
  1059. int j=0;
  1060. for (i = 0; i < (sizeof(struct in_addr)); i++)
  1061. j ^= (unsigned char)(*((char *)&IpAddr + i));
  1062. return j % HASH_TABLE_SIZE;
  1063. }
  1064. DWORD
  1065. CHashTable::DnsResolve()
  1066. {
  1067. PLIST_ENTRY pEntry;
  1068. HashEntry *pHE;
  1069. HOSTENT *pHost;
  1070. BOOL bWorkAvail;
  1071. while(m_bDnsResolveActive) {
  1072. pHE=NULL;
  1073. bWorkAvail=FALSE;
  1074. CSingleLock slHashLock(&m_csHashLock);
  1075. slHashLock.Lock();
  1076. if (!IsListEmpty(&HashTable[PENDING_INDEX])) {
  1077. pEntry=RemoveHeadList(&HashTable[PENDING_INDEX]);
  1078. pHE = CONTAINING_RECORD(pEntry,
  1079. HashEntry,
  1080. Linkage);
  1081. bWorkAvail=TRUE;
  1082. }
  1083. slHashLock.Unlock();
  1084. // Make sure name resolution is outside of lock for perf
  1085. if (bWorkAvail) {
  1086. pHost=gethostbyaddr((char*)&pHE->IpAddr,sizeof(in_addr),AF_INET);
  1087. if (pHost) {
  1088. //Resolution succeeded
  1089. pHE->HostName = pHost->h_name;
  1090. g_HashTable.AddObject(pHE);
  1091. } else {
  1092. // Resolution attempted, failed, cache failure for perf
  1093. ULONG ul = RevertDwordBytes(*(DWORD*)&pHE->IpAddr);
  1094. CIpAddress TmpIpAddr = ul;
  1095. pHE->HostName = (CString)TmpIpAddr;
  1096. g_HashTable.AddObject(pHE);
  1097. }
  1098. } else {
  1099. Sleep(300);
  1100. }
  1101. }
  1102. m_bThreadRunning=FALSE;
  1103. return ERROR_SUCCESS;
  1104. }
  1105. UINT HashResolverCallback(LPVOID pParam)
  1106. {
  1107. g_HashTable.DnsResolve();
  1108. return ERROR_SUCCESS;
  1109. }