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.

1236 lines
30 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows/NT **/
  3. /** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
  4. /**********************************************************************/
  5. /*
  6. info.cpp
  7. FILE HISTORY:
  8. */
  9. #include "stdafx.h"
  10. #include "infoi.h"
  11. #include "rtrstr.h" // common router strings
  12. #include "refresh.h"
  13. #include "dvsview.h"
  14. #include "machine.h"
  15. #include "rtrutilp.h"
  16. // Number of connections that we have made, this is used to
  17. // generate the dwConnectionId
  18. extern long s_cConnections;
  19. DEBUG_DECLARE_INSTANCE_COUNTER(RefreshItem);
  20. /*!--------------------------------------------------------------------------
  21. RouterObjectRefreshTimerProc
  22. -
  23. Author: KennT
  24. ---------------------------------------------------------------------------*/
  25. void RouterRefreshObjectTimerProc(LPARAM lParam, DWORD dwTime)
  26. {
  27. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  28. // The lParam passed in is a pointer to the RouterRefreshObject
  29. // Call through on the RouterRefreshObject to start the query
  30. // object
  31. ((RouterRefreshObject *)lParam)->ExecuteRefresh();
  32. }
  33. /*---------------------------------------------------------------------------
  34. RouterRefreshObjectGroup implementation
  35. ---------------------------------------------------------------------------*/
  36. DEBUG_DECLARE_INSTANCE_COUNTER(RouterRefreshObjectGroup);
  37. RouterRefreshObjectGroup::~RouterRefreshObjectGroup()
  38. {
  39. POSITION p = NULL;
  40. RouterRefreshObject* pObj = NULL;
  41. for(p = m_list.GetHeadPosition(); p != NULL; )
  42. {
  43. pObj = m_list.GetNext(p);
  44. Assert(pObj != NULL);
  45. pObj->SetGroup(NULL);
  46. pObj->Release();
  47. }
  48. m_list.RemoveAll();
  49. DEBUG_DECREMENT_INSTANCE_COUNTER(RouterRefreshObjectGroup);
  50. }
  51. /*!--------------------------------------------------------------------------
  52. RouterRefreshObjectGroup::Join
  53. -
  54. Author: WeiJiang
  55. ---------------------------------------------------------------------------*/
  56. HRESULT RouterRefreshObjectGroup::Join(RouterRefreshObject* pRefresh)
  57. {
  58. Assert(pRefresh);
  59. HRESULT hr = hrOK;
  60. COM_PROTECT_TRY
  61. {
  62. m_list.AddTail(pRefresh);
  63. pRefresh->AddRef();
  64. pRefresh->SetGroup(this);
  65. }
  66. COM_PROTECT_CATCH;
  67. return hr;
  68. }
  69. /*!--------------------------------------------------------------------------
  70. RouterRefreshObjectGroup::Leave
  71. -
  72. Author: WeiJiang
  73. ---------------------------------------------------------------------------*/
  74. HRESULT RouterRefreshObjectGroup::Leave(RouterRefreshObject* pRefresh)
  75. {
  76. POSITION p = m_list.Find(pRefresh);
  77. if (p)
  78. {
  79. Assert(pRefresh == m_list.GetAt(p));
  80. m_list.RemoveAt(p);
  81. pRefresh->SetGroup(NULL);
  82. pRefresh->Release();
  83. }
  84. return S_OK;
  85. }
  86. /*!--------------------------------------------------------------------------
  87. RouterRefreshObjectGroup::Refresh
  88. call each member in the group to DoRefresh
  89. Author: WeiJiang
  90. ---------------------------------------------------------------------------*/
  91. HRESULT RouterRefreshObjectGroup::Refresh()
  92. {
  93. POSITION p = NULL;
  94. RouterRefreshObject* pObj = NULL;
  95. for(p = m_list.GetHeadPosition(); p != NULL; )
  96. {
  97. pObj = m_list.GetNext(p);
  98. Assert(pObj != NULL);
  99. pObj->DoRefresh();
  100. }
  101. return S_OK;
  102. }
  103. /*---------------------------------------------------------------------------
  104. RouterRefreshObject implementation
  105. ---------------------------------------------------------------------------*/
  106. IMPLEMENT_ADDREF_RELEASE(RouterRefreshObject);
  107. DEBUG_DECLARE_INSTANCE_COUNTER(RouterRefreshObject);
  108. STDMETHODIMP RouterRefreshObject::QueryInterface(REFIID iid,void **ppv)
  109. {
  110. *ppv = 0;
  111. if (iid == IID_IUnknown)
  112. *ppv = (IUnknown *) (IRouterRefresh *) this;
  113. else if (iid == IID_IRouterRefresh)
  114. *ppv = (IRouterRefresh *) this;
  115. else if (iid == IID_IRouterRefreshModify)
  116. *ppv = (IRouterRefreshModify *) this;
  117. else
  118. return ThreadHandler::QueryInterface(iid, ppv);
  119. ((IUnknown *) *ppv)->AddRef();
  120. return hrOK;
  121. }
  122. RouterRefreshObject::RouterRefreshObject(HWND hWndSync)
  123. : m_hWndSync(hWndSync),
  124. m_dwSeconds(DEFAULT_REFRESH_INTERVAL),
  125. m_iEventId(-1),
  126. m_pRefreshGroup(NULL),
  127. m_fStarted(FALSE),
  128. m_fInRefresh(FALSE)
  129. {
  130. DEBUG_INCREMENT_INSTANCE_COUNTER(RouterRefreshObject);
  131. InitializeCriticalSection(&m_critsec);
  132. }
  133. RouterRefreshObject::~RouterRefreshObject()
  134. {
  135. // Shut down the timer if its started
  136. Stop();
  137. DEBUG_DECREMENT_INSTANCE_COUNTER(RouterRefreshObject);
  138. DeleteCriticalSection(&m_critsec);
  139. }
  140. /*!--------------------------------------------------------------------------
  141. RouterRefreshObject::GetRefreshInterval
  142. -
  143. Author: KennT
  144. ---------------------------------------------------------------------------*/
  145. STDMETHODIMP RouterRefreshObject::GetRefreshInterval(DWORD *pdwSeconds)
  146. {
  147. RtrCriticalSection rtrCritSec(&m_critsec);
  148. HRESULT hr = hrOK;
  149. if (pdwSeconds == NULL)
  150. return E_INVALIDARG;
  151. COM_PROTECT_TRY
  152. {
  153. if (pdwSeconds)
  154. *pdwSeconds = m_dwSeconds;
  155. }
  156. COM_PROTECT_CATCH;
  157. return hr;
  158. }
  159. /*!--------------------------------------------------------------------------
  160. RouterRefreshObject::GetRefreshInterval
  161. -
  162. Author: KennT
  163. ---------------------------------------------------------------------------*/
  164. STDMETHODIMP RouterRefreshObject::SetRefreshInterval(DWORD dwSeconds)
  165. {
  166. HRESULT hr = hrOK;
  167. if (IsRefreshStarted() == hrOK)
  168. {
  169. Stop();
  170. Start(dwSeconds);
  171. }
  172. else
  173. {
  174. RtrCriticalSection rtrCritSec(&m_critsec);
  175. m_dwSeconds = dwSeconds;
  176. }
  177. return hr;
  178. }
  179. /*!--------------------------------------------------------------------------
  180. RouterRefreshObject::IsInRefresh
  181. -
  182. Author: KennT
  183. ---------------------------------------------------------------------------*/
  184. STDMETHODIMP RouterRefreshObject::IsInRefresh()
  185. {
  186. RtrCriticalSection rtrCritSec(&m_critsec);
  187. HRESULT hr = hrOK;
  188. COM_PROTECT_TRY
  189. {
  190. hr = (m_fInRefresh) ? hrOK : hrFalse;
  191. }
  192. COM_PROTECT_CATCH;
  193. return hr;
  194. }
  195. /*!--------------------------------------------------------------------------
  196. RouterRefreshObject::Refresh
  197. -
  198. Author: KennT
  199. ---------------------------------------------------------------------------*/
  200. STDMETHODIMP RouterRefreshObject::Refresh()
  201. {
  202. if (m_pRefreshGroup)
  203. {
  204. return m_pRefreshGroup->Refresh();
  205. }
  206. else
  207. {
  208. return DoRefresh();
  209. }
  210. }
  211. /*!--------------------------------------------------------------------------
  212. RouterRefreshObject::DoRefresh
  213. -
  214. Author: KennT
  215. ---------------------------------------------------------------------------*/
  216. HRESULT RouterRefreshObject::DoRefresh()
  217. {
  218. RtrCriticalSection rtrCritSec(&m_critsec);
  219. HRESULT hr = hrOK;
  220. COM_PROTECT_TRY
  221. {
  222. // If we are in a refresh cycle, return hrOK
  223. if (m_fInRefresh)
  224. goto Error;
  225. // If we are not in a refresh cycle, then we start one
  226. ExecuteRefresh();
  227. COM_PROTECT_ERROR_LABEL;
  228. }
  229. COM_PROTECT_CATCH;
  230. return hr;
  231. }
  232. /*!--------------------------------------------------------------------------
  233. RouterRefreshObject::Start
  234. -
  235. Author: KennT
  236. ---------------------------------------------------------------------------*/
  237. STDMETHODIMP RouterRefreshObject::Start(DWORD dwSeconds)
  238. {
  239. RtrCriticalSection rtrCritSec(&m_critsec);
  240. HRESULT hr = hrOK;
  241. COM_PROTECT_TRY
  242. {
  243. // If we are already started then end
  244. if (m_fStarted)
  245. goto Error;
  246. // Start the timer going
  247. m_fStarted = TRUE;
  248. m_dwSeconds = dwSeconds;
  249. m_iEventId = g_timerMgr.AllocateTimer(RouterRefreshObjectTimerProc,
  250. (LPARAM) this,
  251. dwSeconds * 1000);
  252. if (m_iEventId == -1)
  253. {
  254. m_fStarted = FALSE;
  255. hr = HRESULT_FROM_WIN32(::GetLastError());
  256. }
  257. COM_PROTECT_ERROR_LABEL;
  258. }
  259. COM_PROTECT_CATCH;
  260. return hr;
  261. }
  262. /*!--------------------------------------------------------------------------
  263. RouterRefreshObject::Stop
  264. -
  265. Author: KennT
  266. ---------------------------------------------------------------------------*/
  267. STDMETHODIMP RouterRefreshObject::Stop()
  268. {
  269. RtrCriticalSection rtrCritSec(&m_critsec);
  270. HRESULT hr = hrOK;
  271. COM_PROTECT_TRY
  272. {
  273. if (!m_fStarted)
  274. {
  275. Assert(m_iEventId == -1);
  276. goto Error;
  277. }
  278. // Stop the timer
  279. if (m_iEventId != -1)
  280. g_timerMgr.FreeTimer(m_iEventId);
  281. m_iEventId = -1;
  282. ReleaseThreadHandler();
  283. WaitForThreadToExit();
  284. m_fStarted = FALSE;
  285. COM_PROTECT_ERROR_LABEL;
  286. }
  287. COM_PROTECT_CATCH;
  288. return hr;
  289. }
  290. /*!--------------------------------------------------------------------------
  291. RouterRefreshObject::IsRefreshStarted
  292. -
  293. Author: KennT
  294. ---------------------------------------------------------------------------*/
  295. STDMETHODIMP RouterRefreshObject::IsRefreshStarted()
  296. {
  297. RtrCriticalSection rtrCritSec(&m_critsec);
  298. HRESULT hr = hrOK;
  299. COM_PROTECT_TRY
  300. {
  301. hr = m_fStarted ? hrOK : hrFalse;
  302. Assert((m_fStarted == FALSE) || (m_iEventId != -1));
  303. }
  304. COM_PROTECT_CATCH;
  305. return hr;
  306. }
  307. /*!--------------------------------------------------------------------------
  308. RouterRefreshObject::AdviseRefresh
  309. -
  310. Author: KennT
  311. ---------------------------------------------------------------------------*/
  312. STDMETHODIMP RouterRefreshObject::AdviseRefresh(IRtrAdviseSink *pRtrAdviseSink,
  313. LONG_PTR *pdwConnection,
  314. LPARAM lUserParam)
  315. {
  316. Assert(pRtrAdviseSink);
  317. Assert(pdwConnection);
  318. RtrCriticalSection rtrCritSec(&m_critsec);
  319. DWORD dwConnId;
  320. HRESULT hr = hrOK;
  321. COM_PROTECT_TRY
  322. {
  323. dwConnId = (DWORD) InterlockedIncrement(&s_cConnections);
  324. CORg( m_AdviseList.AddConnection(pRtrAdviseSink, dwConnId, lUserParam) );
  325. *pdwConnection = dwConnId;
  326. COM_PROTECT_ERROR_LABEL;
  327. }
  328. COM_PROTECT_CATCH;
  329. return hr;
  330. }
  331. /*!--------------------------------------------------------------------------
  332. RouterRefreshObject::AddRouter
  333. -
  334. Author: WeiJiang
  335. ---------------------------------------------------------------------------*/
  336. STDMETHODIMP RouterRefreshObject::AddRouterObject(REFIID riid, IUnknown *pUnk)
  337. {
  338. HRESULT hr = S_OK;
  339. IRouterInfo * pRouterInfo;
  340. if (riid != IID_IRouterInfo)
  341. return E_NOINTERFACE;
  342. pRouterInfo = reinterpret_cast<IRouterInfo *>(pUnk);
  343. COM_PROTECT_TRY
  344. {
  345. CRouterInfoRefreshItem* pRefreshItem =
  346. new CRouterInfoRefreshItem(pRouterInfo);
  347. if (pRefreshItem)
  348. {
  349. // check for duplicates
  350. if (S_FALSE == m_listElements.AddRefreshItem(pRefreshItem))
  351. delete pRefreshItem;
  352. }
  353. }
  354. COM_PROTECT_CATCH;
  355. return hr;
  356. }
  357. /*!--------------------------------------------------------------------------
  358. RouterRefreshObject::RemoveRouterObject
  359. -
  360. Author: WeiJiang
  361. ---------------------------------------------------------------------------*/
  362. STDMETHODIMP RouterRefreshObject::RemoveRouterObject(REFIID riid, IUnknown *pUnk)
  363. {
  364. if (riid != IID_IRouterInfo)
  365. return E_NOINTERFACE;
  366. IRouterInfo * pRouterInfo = reinterpret_cast<IRouterInfo *>(pUnk);
  367. CRouterInfoRefreshItem RefreshItem(pRouterInfo);
  368. return m_listElements.RemoveRefreshItem(RefreshItem);
  369. }
  370. /*!--------------------------------------------------------------------------
  371. RouterRefreshObject::AddStatusNode
  372. -
  373. Author: KennT
  374. ---------------------------------------------------------------------------*/
  375. HRESULT RouterRefreshObject::AddStatusNode(DomainStatusHandler* pStatusHandler, ITFSNode *pServerNode)
  376. {
  377. HRESULT hr = S_OK;
  378. COM_PROTECT_TRY
  379. {
  380. CStatusNodeRefreshItem* pRefreshItem = new CStatusNodeRefreshItem(pStatusHandler, pServerNode);
  381. if (pRefreshItem)
  382. {
  383. // Check for duplicates
  384. if (S_FALSE == m_listElements.AddRefreshItem(pRefreshItem))
  385. delete pRefreshItem;
  386. }
  387. }
  388. COM_PROTECT_CATCH;
  389. return hr;
  390. }
  391. /*!--------------------------------------------------------------------------
  392. RouterRefreshObject::RemoveRouter
  393. -
  394. Author: KennT
  395. ---------------------------------------------------------------------------*/
  396. HRESULT RouterRefreshObject::RemoveStatusNode(ITFSNode *pServerNode)
  397. {
  398. CStatusNodeRefreshItem RefreshItem((DomainStatusHandler *)0x1, pServerNode);
  399. return m_listElements.RemoveRefreshItem(RefreshItem);
  400. }
  401. /*!--------------------------------------------------------------------------
  402. RouterRefreshObject::NotifyRefresh
  403. -
  404. Author: KennT
  405. ---------------------------------------------------------------------------*/
  406. STDMETHODIMP RouterRefreshObject::NotifyRefresh()
  407. {
  408. RtrCriticalSection rtrCritSec(&m_critsec);
  409. HRESULT hr = hrOK;
  410. COM_PROTECT_TRY
  411. {
  412. m_AdviseList.NotifyChange(ROUTER_REFRESH, 0, 0);
  413. }
  414. COM_PROTECT_CATCH;
  415. return hr;
  416. }
  417. /*!--------------------------------------------------------------------------
  418. RouterRefreshObject::UnadviseRefresh
  419. -
  420. Author: KennT
  421. ---------------------------------------------------------------------------*/
  422. STDMETHODIMP RouterRefreshObject::UnadviseRefresh(LONG_PTR dwConnection)
  423. {
  424. RtrCriticalSection rtrCritSec(&m_critsec);
  425. HRESULT hr = hrOK;
  426. COM_PROTECT_TRY
  427. {
  428. hr = m_AdviseList.RemoveConnection(dwConnection);
  429. }
  430. COM_PROTECT_CATCH;
  431. return hr;
  432. }
  433. /*!--------------------------------------------------------------------------
  434. RouterRefreshObject::ExecuteRefresh
  435. -
  436. Author: KennT
  437. ---------------------------------------------------------------------------*/
  438. void RouterRefreshObject::ExecuteRefresh()
  439. {
  440. SPITFSQueryObject spQuery;
  441. RouterRefreshQueryObject * pQuery;
  442. // Trace0("Refresh started\n");
  443. if (m_fInRefresh)
  444. return;
  445. m_fInRefresh = TRUE;
  446. // Create the Query Object
  447. pQuery = new RouterRefreshQueryObject;
  448. spQuery = pQuery;
  449. pQuery->Init(&m_listElements);
  450. // Need to start the background thread
  451. Verify( StartBackgroundThread(NULL, m_hWndSync, spQuery) );
  452. }
  453. HRESULT RouterRefreshObject::OnNotifyError(LPARAM lParam)
  454. {
  455. return hrOK;
  456. }
  457. HRESULT RouterRefreshObject::OnNotifyHaveData(LPARAM lParam)
  458. {
  459. LONG_PTR RefreshItemKey = (LONG_PTR)lParam;
  460. RouterRefreshQueryElement* pCur = NULL;
  461. SPRouterRefreshQueryElement spPre;
  462. HRESULT hr = S_OK;
  463. // notify every one on the list, till lParam == Key of the refresh item
  464. // enumerate and call TryNotify ...
  465. if (RefreshItemKey)
  466. {
  467. do
  468. {
  469. pCur = m_listElements.Next(spPre);
  470. if (pCur)
  471. pCur->TryNotifyQueryResult();
  472. spPre.Free();
  473. spPre = pCur;
  474. } while(pCur && pCur->GetRefreshItem()->GetKey() != RefreshItemKey);
  475. }
  476. return hrOK;
  477. }
  478. HRESULT RouterRefreshObject::OnNotifyExiting(LPARAM lParam)
  479. {
  480. // Trace0("RouterRefreshObject::OnNotifyExiting()\n");
  481. // need to do the various actions at this point
  482. // Merge the tree with the already existing tree
  483. IRouterInfo* pRouter = (IRouterInfo*)lParam;
  484. SPRouterRefreshQueryElement spPre;
  485. RouterRefreshQueryElement* pCur = NULL;
  486. HRESULT hr = S_OK;
  487. // notify every one on the list, till lParam == IRouterInfo*
  488. // enumerate and call TryNotify ...
  489. do
  490. {
  491. pCur = m_listElements.Next(spPre);
  492. if (pCur)
  493. pCur->TryNotifyQueryResult();
  494. spPre.Free();
  495. spPre = pCur;
  496. } while(pCur);
  497. // Now notify all of the registered handlers
  498. NotifyRefresh();
  499. ReleaseThreadHandler();
  500. WaitForThreadToExit();
  501. m_fInRefresh = FALSE;
  502. return hrOK;
  503. }
  504. /*!--------------------------------------------------------------------------
  505. RtrRefreshTimerProc
  506. This is used by the CTimerMgr as its callback proc. We then call
  507. the Refresh code.
  508. Author: KennT
  509. ---------------------------------------------------------------------------*/
  510. void CALLBACK RtrRefreshTimerProc(HWND hWnd, UINT uMsg, UINT_PTR nIdEvent,
  511. DWORD dwTime)
  512. {
  513. RtrCriticalSection rtrCritSec(&g_timerMgr.m_critsec);
  514. CTimerDesc *pDesc = g_timerMgr.GetTimerDesc(nIdEvent);
  515. if (pDesc)
  516. {
  517. (*(pDesc->refreshProc))(pDesc->lParam, dwTime);
  518. }
  519. }
  520. /*---------------------------------------------------------------------------
  521. Global variable: g_timerMgr
  522. ---------------------------------------------------------------------------*/
  523. CTimerMgr g_timerMgr;
  524. DEBUG_DECLARE_INSTANCE_COUNTER(CTimerMgr);
  525. /*!--------------------------------------------------------------------------
  526. CTimerMgr::CTimerMgr
  527. -
  528. Author: EricDav
  529. ---------------------------------------------------------------------------*/
  530. CTimerMgr::CTimerMgr()
  531. {
  532. InitializeCriticalSection(&m_critsec);
  533. }
  534. /*!--------------------------------------------------------------------------
  535. CTimerMgr::~CTimerMgr
  536. -
  537. Author: EricDav
  538. ---------------------------------------------------------------------------*/
  539. CTimerMgr::~CTimerMgr()
  540. {
  541. CTimerDesc * pTimerDesc;
  542. for (int i = GetUpperBound(); i >= 0; --i)
  543. {
  544. pTimerDesc = GetAt(i);
  545. if (pTimerDesc->uTimerId != 0)
  546. FreeTimer(i);
  547. delete pTimerDesc;
  548. }
  549. DeleteCriticalSection(&m_critsec);
  550. }
  551. /*!--------------------------------------------------------------------------
  552. CTimerMgr::AllocateTimer
  553. -
  554. Author: EricDav
  555. ---------------------------------------------------------------------------*/
  556. int
  557. CTimerMgr::AllocateTimer
  558. (
  559. REFRESHPROC RefreshProc,
  560. LPARAM lParam,
  561. UINT uTimerInterval
  562. )
  563. {
  564. RtrCriticalSection rtrCritSec(&m_critsec);
  565. CTimerDesc * pTimerDesc = NULL;
  566. // look for an empty slot
  567. for (int i = GetUpperBound(); i >= 0; --i)
  568. {
  569. pTimerDesc = GetAt(i);
  570. if (pTimerDesc->uTimerId == 0)
  571. break;
  572. }
  573. // did we find one? if not allocate one
  574. if (i < 0)
  575. {
  576. pTimerDesc = new CTimerDesc;
  577. pTimerDesc->lParam = 0;
  578. pTimerDesc->uTimerInterval = 0;
  579. pTimerDesc->refreshProc = NULL;
  580. pTimerDesc->uTimerId = 0;
  581. Add(pTimerDesc);
  582. i = GetUpperBound();
  583. }
  584. pTimerDesc->uTimerId = SetTimer(NULL, 0, uTimerInterval, RtrRefreshTimerProc);
  585. if (pTimerDesc->uTimerId == 0)
  586. return -1;
  587. pTimerDesc->lParam = lParam;
  588. pTimerDesc->uTimerInterval = uTimerInterval;
  589. pTimerDesc->refreshProc = RefreshProc;
  590. return i;
  591. }
  592. /*!--------------------------------------------------------------------------
  593. CTimerMgr::FreeTimer
  594. -
  595. Author: EricDav
  596. ---------------------------------------------------------------------------*/
  597. void
  598. CTimerMgr::FreeTimer
  599. (
  600. int uEventId
  601. )
  602. {
  603. RtrCriticalSection rtrCritSec(&m_critsec);
  604. CTimerDesc * pTimerDesc;
  605. Assert(uEventId <= GetUpperBound());
  606. if (uEventId > GetUpperBound())
  607. return;
  608. pTimerDesc = GetAt(uEventId);
  609. ::KillTimer(NULL, pTimerDesc->uTimerId);
  610. pTimerDesc->lParam = 0;
  611. pTimerDesc->uTimerId = 0;
  612. pTimerDesc->uTimerInterval = 0;
  613. pTimerDesc->refreshProc = NULL;
  614. }
  615. /*!--------------------------------------------------------------------------
  616. CTimerMgr::GetTimerDesc
  617. -
  618. Author: EricDav
  619. ---------------------------------------------------------------------------*/
  620. CTimerDesc *
  621. CTimerMgr::GetTimerDesc
  622. (
  623. INT_PTR uTimerId
  624. )
  625. {
  626. RtrCriticalSection rtrCritSec(&m_critsec);
  627. CTimerDesc * pTimerDesc;
  628. for (int i = GetUpperBound(); i >= 0; --i)
  629. {
  630. pTimerDesc = GetAt(i);
  631. if (pTimerDesc->uTimerId == (UINT) uTimerId)
  632. return pTimerDesc;
  633. }
  634. return NULL;
  635. }
  636. /*!--------------------------------------------------------------------------
  637. CTimerMgr::ChangeInterval
  638. -
  639. Author: EricDav
  640. ---------------------------------------------------------------------------*/
  641. void
  642. CTimerMgr::ChangeInterval
  643. (
  644. int uEventId,
  645. UINT uNewInterval
  646. )
  647. {
  648. RtrCriticalSection rtrCritSec(&m_critsec);
  649. Assert(uEventId <= GetUpperBound());
  650. if (uEventId > GetUpperBound())
  651. return;
  652. CTimerDesc tempTimerDesc;
  653. CTimerDesc * pTimerDesc;
  654. pTimerDesc = GetAt(uEventId);
  655. // kill the old timer
  656. ::KillTimer(NULL, pTimerDesc->uTimerId);
  657. // set a new one with the new interval
  658. pTimerDesc->uTimerId = ::SetTimer(NULL, 0, uNewInterval, RtrRefreshTimerProc);
  659. }
  660. /*---------------------------------------------------------------------------
  661. RouterRefreshQueryObject implementation
  662. ---------------------------------------------------------------------------*/
  663. DEBUG_DECLARE_INSTANCE_COUNTER(RouterRefreshQueryObject);
  664. RouterRefreshQueryObject::RouterRefreshQueryObject()
  665. {
  666. }
  667. STDMETHODIMP RouterRefreshQueryObject::Execute()
  668. {
  669. // for each router info in the queue, run load
  670. // after each load of router info, post message
  671. // WM_HIDDENWND_INDEX_HAVEDATA
  672. SPRouterRefreshQueryElement spPre;
  673. RouterRefreshQueryElement* pCur = NULL;
  674. HRESULT hr = S_OK;
  675. // notify every one on the list, till lParam == IRouterInfo*
  676. // enumerate and call TryNotify ...
  677. Assert(m_plistElements);
  678. do
  679. {
  680. pCur = m_plistElements->Next(spPre);
  681. if (pCur)
  682. pCur->DoQuery(m_hHiddenWnd, m_uMsgBase, m_spHandler);
  683. spPre.Free();
  684. spPre = pCur;
  685. }while(pCur);
  686. return hrFalse;
  687. }
  688. STDMETHODIMP RouterRefreshQueryObject::OnThreadExit()
  689. {
  690. ::PostMessage(m_hHiddenWnd, m_uMsgBase + WM_HIDDENWND_INDEX_EXITING,
  691. (WPARAM)(ITFSThreadHandler *)m_spHandler, 0);
  692. // Trace0("Exiting RouterRefreshQueryObject::Execute()\n");
  693. return hrOK;
  694. }
  695. //=========================================
  696. // CRouterInfoRefreshItem implementation
  697. //
  698. DEBUG_DECLARE_INSTANCE_COUNTER(CRouterInfoRefreshItem);
  699. /*!--------------------------------------------------------------------------
  700. CRouterInfoRefreshItem::NotifyQueryResult
  701. -
  702. Author: WeiJiang
  703. ---------------------------------------------------------------------------*/
  704. HRESULT CRouterInfoRefreshItem::NotifyQueryResult()
  705. {
  706. // get the flag to see if need to notify, if not return S_FALSE
  707. // TRACE(_T("\nAUTOREFRESH!!RouterInfoRefreshItem!!Merge on %8x\n"), GetKey());
  708. // need to do the various actions at this point
  709. // Merge the tree with the already existing tree
  710. HRESULT hr = S_OK;
  711. m_cs.Lock();
  712. COM_PROTECT_TRY
  713. {
  714. hr = m_pRouter->Merge(m_spRouterNew);
  715. m_spRouterNew->DoDisconnect();
  716. }
  717. COM_PROTECT_CATCH;
  718. m_cs.Unlock();
  719. return hr;
  720. };
  721. /*!--------------------------------------------------------------------------
  722. CRouterInfoRefreshItem::DoQuery
  723. -
  724. Author: WeiJiang
  725. ---------------------------------------------------------------------------*/
  726. HRESULT CRouterInfoRefreshItem::DoQuery(HWND hwndHidden, UINT uMsgBase, ITFSThreadHandler* pHandler) // this happens in background worker thread
  727. {
  728. // TRACE(_T("\nAUTOREFRESH!!RouterInfoRefreshItem!!Do query on %8x\n"), GetKey());
  729. // create new RouterInfo, if newRouterInfo is NULL
  730. // Create the dummy router info
  731. HRESULT hr = S_OK;
  732. m_cs.Lock();
  733. COM_PROTECT_TRY
  734. {
  735. if (!m_spRouterNew)
  736. hr = CreateRouterInfo(&m_spRouterNew, NULL, m_pRouter->GetMachineName());
  737. // do query on newRouterInfo
  738. Assert(m_pRouter);
  739. if (hr == S_OK)
  740. {
  741. TransferCredentials ( m_pRouter, m_spRouterNew );
  742. m_pRouter->DoDisconnect();
  743. hr = m_spRouterNew->Load(m_pRouter->GetMachineName(), NULL);
  744. }
  745. }
  746. COM_PROTECT_CATCH;
  747. m_cs.Unlock();
  748. return hr;
  749. };
  750. //=========================================
  751. // CMachineNodeDataRefreshItem implementation
  752. DEBUG_DECLARE_INSTANCE_COUNTER(CStatusNodeRefreshItem);
  753. CStatusNodeRefreshItem::CStatusNodeRefreshItem(DomainStatusHandler* pStatusHandler, ITFSNode *pServerNode)
  754. : m_pNode(pServerNode) ,
  755. m_pStatusHandler(pStatusHandler),
  756. m_pData(NULL)
  757. {
  758. Assert(pStatusHandler);
  759. Assert(pServerNode);
  760. DMVNodeData *pData;
  761. MachineNodeData *pMachineData;
  762. pData = GET_DMVNODEDATA(m_pNode);
  763. Assert(pData);
  764. pMachineData = pData->m_spMachineData;
  765. Assert(pMachineData);
  766. m_strMachineName = pMachineData->m_stMachineName;
  767. }
  768. CStatusNodeRefreshItem::~CStatusNodeRefreshItem()
  769. {
  770. TerminateBlockingThread();
  771. if (m_pData)
  772. {
  773. m_pData->Release();
  774. m_pData = NULL;
  775. }
  776. };
  777. HRESULT CStatusNodeRefreshItem::NotifyQueryResult()
  778. {
  779. // get the flag to see if need to notify, if not return S_FALSE
  780. // TRACE(_T("\nAUTOREFRESH!!RouterInfoRefreshItem!!Sync node data on %8x\n"), GetKey());
  781. HRESULT hr = S_OK;
  782. m_cs.Lock();
  783. COM_PROTECT_TRY
  784. {
  785. // set the new node data
  786. DMVNodeData *pData;
  787. pData = GET_DMVNODEDATA(m_pNode);
  788. hr = pData->MergeMachineNodeData(m_pData);
  789. if (hr == S_OK)
  790. hr = m_pStatusHandler->UpdateSubItemUI(m_pNode);
  791. }
  792. COM_PROTECT_CATCH;
  793. m_cs.Unlock();
  794. // ssync on the node
  795. return hr;
  796. };
  797. HRESULT CStatusNodeRefreshItem::DoQuery(HWND hwndHidden, UINT uMsgBase, ITFSThreadHandler* pHandler) // this happens in background worker thread
  798. {
  799. // TRACE(_T("\nAUTOREFRESH!!RouterInfoRefreshItem!!Do query on %8x\n"), GetKey());
  800. // create a new machine node data, load informaiton,
  801. HRESULT hr = S_OK;
  802. m_cs.Lock();
  803. COM_PROTECT_TRY
  804. {
  805. if (!m_pData)
  806. {
  807. m_pData = new MachineNodeData;
  808. m_pData->Init(m_strMachineName);
  809. }
  810. m_pData->Load();
  811. }
  812. COM_PROTECT_CATCH;
  813. m_cs.Unlock();
  814. return hr;
  815. };
  816. //=========================================
  817. // RouterRefreshQueryElement implementation
  818. DEBUG_DECLARE_INSTANCE_COUNTER(RouterRefreshQueryElement);
  819. HRESULT RouterRefreshQueryElement::SetRefreshItem(RefreshItem* pItem)
  820. {
  821. if (m_cs.Lock() == 0) return E_FAIL;
  822. m_pItem = pItem;
  823. m_cs.Unlock();
  824. return S_OK;
  825. };
  826. RefreshItem* RouterRefreshQueryElement::GetRefreshItem()
  827. {
  828. RefreshItem* pItem;
  829. m_cs.Lock();
  830. pItem = m_pItem;
  831. m_cs.Unlock();
  832. return pItem;
  833. };
  834. /*!--------------------------------------------------------------------------
  835. RouterRefreshQueryElement::TryNotifyQueryResult
  836. to detect if the query done, yet to Notify
  837. Author: WeiJiang
  838. ---------------------------------------------------------------------------*/
  839. HRESULT RouterRefreshQueryElement::TryNotifyQueryResult()
  840. {
  841. HRESULT hr = S_OK;
  842. RefreshItem* pItem = NULL;
  843. // get the flag to see if need to notify, if not return S_FALSE
  844. if (GetStatus() == RouterQuery_ToNotify)
  845. {
  846. // TRACE(_T("\nAUTOREFRESH!!TryNotifyQueryResult on %8x\n"), m_pItem->GetKey());
  847. // need to do the various actions at this point
  848. // Merge the tree with the already existing tree
  849. pItem = GetRefreshItem();
  850. }
  851. if(pItem)
  852. {
  853. hr = pItem->NotifyQueryResult();
  854. // after notify, set the flag, return S_OK
  855. SetStatus(RouterQuery_NoAction);
  856. }
  857. return hr;
  858. };
  859. void RouterRefreshQueryElement::PostNotify(HWND hwndHidden, UINT uMsgBase, ITFSThreadHandler* pHandler) // this happens in background worker thread
  860. {
  861. // set ready to notify flag
  862. SetStatus(RouterQuery_ToNotify);
  863. // Post done to hidden window
  864. ::PostMessage(hwndHidden, uMsgBase + WM_HIDDENWND_INDEX_HAVEDATA,
  865. (WPARAM)pHandler, (LPARAM)m_pItem->GetKey());
  866. }
  867. HRESULT RouterRefreshQueryElement::DoQuery(HWND hwndHidden, UINT uMsgBase, ITFSThreadHandler* pHandler) // this happens in background worker thread
  868. {
  869. HRESULT hr = S_OK;
  870. // TRACE(_T("\nAUTOREFRESH!!Do query on %8x\n"), m_pItem->GetKey());
  871. RefreshItem* pItem = GetRefreshItem();
  872. COM_PROTECT_TRY
  873. {
  874. // asked to do query, do it anyway, no matter what's the status
  875. // set blocking current thread, in case, this query blocks
  876. pItem->SetBlockingThread(GetCurrentThread());
  877. hr = pItem->DoQuery(hwndHidden, uMsgBase, pHandler);
  878. if (hr == S_OK)
  879. {
  880. PostNotify(hwndHidden, uMsgBase, pHandler);
  881. }
  882. // it's not blocked, reset it
  883. pItem->ResetBlockingThread();
  884. }
  885. COM_PROTECT_CATCH;
  886. return hr;
  887. };
  888. RouterRefreshQueryElementList::~RouterRefreshQueryElementList()
  889. {
  890. POSITION p = NULL;
  891. RouterRefreshQueryElement* pEle = NULL;
  892. m_cs.Lock();
  893. p = m_list.GetHeadPosition();
  894. for(p = m_list.GetHeadPosition(); p != NULL; )
  895. {
  896. pEle = m_list.GetNext(p);
  897. pEle->Release();
  898. }
  899. m_list.RemoveAll();
  900. m_cs.Unlock();
  901. }
  902. HRESULT RouterRefreshQueryElementList::AddRefreshItem(RefreshItem* pItem) // no ref on IRouterInfo
  903. {
  904. POSITION p = NULL;
  905. RouterRefreshQueryElement* pE = NULL;
  906. HRESULT hr = S_OK;
  907. m_cs.Lock();
  908. try{
  909. for (p = m_list.GetHeadPosition(); p != NULL; )
  910. {
  911. pE = m_list.GetNext(p);
  912. // already added, so only addRef
  913. if (pItem->GetKey() == pE->GetRefreshItem()->GetKey())
  914. {
  915. break;
  916. }
  917. }
  918. if (p != NULL) // found
  919. {
  920. pE->AddRef();
  921. hr = S_FALSE; // we are not keeping the pItem
  922. }
  923. else
  924. {
  925. CComObject<RouterRefreshQueryElement>* pEle = NULL;
  926. hr = CComObject<RouterRefreshQueryElement>::CreateInstance(&pEle);
  927. if ( FHrSucceeded(hr) )
  928. {
  929. Assert(pEle);
  930. pEle->SetRefreshItem(pItem);
  931. pEle->AddRef();
  932. m_list.AddTail(pEle);
  933. }
  934. }
  935. }
  936. catch(CMemoryException* pException)
  937. {
  938. pException->Delete();
  939. hr = E_OUTOFMEMORY;
  940. }
  941. catch(...)
  942. {
  943. m_cs.Unlock();
  944. throw;
  945. }
  946. m_cs.Unlock();
  947. return hr;
  948. }
  949. HRESULT RouterRefreshQueryElementList::RemoveRefreshItem(RefreshItem& Item) // no ref on IRouterInfo
  950. {
  951. HRESULT hr = hrOK;
  952. POSITION p = NULL;
  953. POSITION cp = NULL;
  954. RouterRefreshQueryElement* pE = NULL;
  955. m_cs.Lock();
  956. try{
  957. for(p = m_list.GetHeadPosition(); p != NULL; )
  958. {
  959. cp = p;
  960. pE = m_list.GetNext(p);
  961. if (Item.GetKey() == pE->GetRefreshItem()->GetKey()) // already added, will release on Ele object
  962. {
  963. break;
  964. }
  965. // This is not the one we are looking for.
  966. cp = NULL;
  967. }
  968. if (cp != NULL) // found
  969. {
  970. pE->Release(); //remove from the refresh list
  971. m_list.RemoveAt(cp);
  972. }
  973. else
  974. hr = S_FALSE;
  975. }
  976. catch(...)
  977. {
  978. m_cs.Unlock();
  979. throw;
  980. }
  981. m_cs.Unlock();
  982. return hr;
  983. }
  984. RouterRefreshQueryElement* RouterRefreshQueryElementList::Next(RouterRefreshQueryElement* pEle) // AddRef on Ele Object
  985. {
  986. RouterRefreshQueryElement* pNext = NULL;
  987. m_cs.Lock();
  988. if (pEle == NULL)
  989. {
  990. if (m_list.GetCount() != 0) // asking for the first element
  991. pNext = m_list.GetHead();
  992. }
  993. else
  994. {
  995. POSITION p;
  996. // find the current one
  997. for(p = m_list.GetHeadPosition(); p != NULL; )
  998. {
  999. if (pEle == m_list.GetNext(p))
  1000. {
  1001. if (p != NULL)
  1002. pNext = m_list.GetAt(p);
  1003. break;
  1004. }
  1005. }
  1006. }
  1007. m_cs.Unlock();
  1008. if (pNext)
  1009. pNext->AddRef();
  1010. return pNext;
  1011. }