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.

917 lines
20 KiB

  1. // ClientConsoleDoc.cpp : implementation of the CClientConsoleDoc class
  2. //
  3. #include "stdafx.h"
  4. #define __FILE_ID__ 2
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. extern CClientConsoleApp theApp;
  11. /////////////////////////////////////////////////////////////////////////////
  12. // CClientConsoleDoc
  13. IMPLEMENT_DYNCREATE(CClientConsoleDoc, CDocument)
  14. BEGIN_MESSAGE_MAP(CClientConsoleDoc, CDocument)
  15. //{{AFX_MSG_MAP(CClientConsoleDoc)
  16. // NOTE - the ClassWizard will add and remove mapping macros here.
  17. // DO NOT EDIT what you see in these blocks of generated code!
  18. //}}AFX_MSG_MAP
  19. END_MESSAGE_MAP()
  20. /////////////////////////////////////////////////////////////////////////////
  21. // CClientConsoleDoc construction/destruction
  22. //
  23. // Static members:
  24. //
  25. HANDLE CClientConsoleDoc::m_hShutdownEvent = NULL;
  26. BOOL CClientConsoleDoc::m_bShuttingDown = FALSE;
  27. CClientConsoleDoc::CClientConsoleDoc() :
  28. m_bRefreshingServers (FALSE),
  29. m_bWin9xPrinterFormat(FALSE)
  30. {}
  31. CClientConsoleDoc::~CClientConsoleDoc()
  32. {
  33. //
  34. // The list of servers is not freed and servers and their folders are not deleted.
  35. // The background threads may still be alive and use the CServerNode and CFolder objects.
  36. // The main thread doesn�t wait for the background threads termination to prevent application hanging.
  37. //
  38. if (m_hShutdownEvent)
  39. {
  40. CloseHandle (m_hShutdownEvent);
  41. m_hShutdownEvent = NULL;
  42. }
  43. }
  44. DWORD
  45. CClientConsoleDoc::Init ()
  46. /*++
  47. Routine name : CClientConsoleDoc::Init
  48. Routine description:
  49. Initializes document events and maps
  50. Author:
  51. Eran Yariv (EranY), Feb, 2000
  52. Arguments:
  53. Return Value:
  54. Standard Win32 error code
  55. --*/
  56. {
  57. DWORD dwRes = ERROR_SUCCESS;
  58. DBG_ENTER(TEXT("CClientConsoleDoc::Init"), dwRes);
  59. //
  60. // Create the shutdown event. This event will be signaled when the app is
  61. // about to quit.
  62. //
  63. ASSERTION (NULL == m_hShutdownEvent);
  64. m_hShutdownEvent = CreateEvent (NULL, // No security
  65. TRUE, // Manual reset
  66. FALSE, // Starts clear
  67. NULL); // Unnamed
  68. if (NULL == m_hShutdownEvent)
  69. {
  70. dwRes = GetLastError ();
  71. CALL_FAIL (STARTUP_ERR, TEXT("CreateEvent"), dwRes);
  72. PopupError (dwRes);
  73. return dwRes;
  74. }
  75. //
  76. // Init the map of notification messages from the servers
  77. //
  78. dwRes = CServerNode::InitMsgsMap ();
  79. if (ERROR_SUCCESS != dwRes)
  80. {
  81. CALL_FAIL (MEM_ERR, TEXT("CServerNode::InitMsgsMap"), dwRes);
  82. PopupError (dwRes);
  83. return dwRes;
  84. }
  85. ASSERTION (ERROR_SUCCESS == dwRes);
  86. return dwRes;
  87. } // CClientConsoleDoc::Init
  88. BOOL CClientConsoleDoc::OnNewDocument()
  89. {
  90. BOOL bRes = FALSE;
  91. DBG_ENTER(TEXT("CClientConsoleDoc::OnNewDocument"), bRes);
  92. if (!CDocument::OnNewDocument())
  93. {
  94. return bRes;
  95. }
  96. if(theApp.IsCmdLineSingleServer())
  97. {
  98. //
  99. // get command line server name
  100. //
  101. try
  102. {
  103. m_cstrSingleServer = theApp.GetCmdLineSingleServerName();
  104. }
  105. catch (...)
  106. {
  107. CALL_FAIL (MEM_ERR, TEXT("CString::operator ="), ERROR_NOT_ENOUGH_MEMORY);
  108. PopupError (ERROR_NOT_ENOUGH_MEMORY);
  109. return bRes;
  110. }
  111. }
  112. DWORD dwRes = Init ();
  113. if (ERROR_SUCCESS != dwRes)
  114. {
  115. CALL_FAIL (GENERAL_ERR, TEXT("CClientConsoleDoc::Init"), dwRes);
  116. return bRes;
  117. }
  118. bRes = TRUE;
  119. return bRes;
  120. }
  121. /////////////////////////////////////////////////////////////////////////////
  122. // CClientConsoleDoc serialization
  123. void CClientConsoleDoc::Serialize(CArchive& ar)
  124. {
  125. if (ar.IsStoring())
  126. {
  127. // TODO: add storing code here
  128. }
  129. else
  130. {
  131. // TODO: add loading code here
  132. }
  133. }
  134. /////////////////////////////////////////////////////////////////////////////
  135. // CClientConsoleDoc diagnostics
  136. #ifdef _DEBUG
  137. void CClientConsoleDoc::AssertValid() const
  138. {
  139. CDocument::AssertValid();
  140. }
  141. void CClientConsoleDoc::Dump(CDumpContext& dc) const
  142. {
  143. CDocument::Dump(dc);
  144. }
  145. #endif //_DEBUG
  146. /////////////////////////////////////////////////////////////////////////////
  147. // CClientConsoleDoc commands
  148. DWORD
  149. CClientConsoleDoc::AddServerNode (
  150. LPCTSTR lpctstrServer
  151. )
  152. /*++
  153. Routine name : CClientConsoleDoc::AddServerNode
  154. Routine description:
  155. Adds a new server node to the servers list and initializes it
  156. Author:
  157. Eran Yariv (EranY), Feb, 2000
  158. Arguments:
  159. lpctstrServer [in] - Server name
  160. Return Value:
  161. Standard Win32 error code
  162. --*/
  163. {
  164. DWORD dwRes = ERROR_SUCCESS;
  165. DBG_ENTER(TEXT("CClientConsoleDoc::AddServerNode"), dwRes, TEXT("%s"), lpctstrServer);
  166. CServerNode *pServerNode = NULL;
  167. //
  168. // Create the new server node
  169. //
  170. try
  171. {
  172. pServerNode = new CServerNode;
  173. }
  174. catch (...)
  175. {
  176. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  177. CALL_FAIL (MEM_ERR, TEXT ("new CServerNode"), dwRes);
  178. PopupError (dwRes);
  179. return dwRes;
  180. }
  181. //
  182. // Init the server
  183. //
  184. dwRes = pServerNode->Init (lpctstrServer);
  185. if (ERROR_SUCCESS != dwRes)
  186. {
  187. pServerNode->Destroy ();
  188. PopupError (dwRes);
  189. return dwRes;
  190. }
  191. //
  192. // Enter the (initialized) node at the end of the list
  193. //
  194. try
  195. {
  196. m_ServersList.push_back (pServerNode);
  197. }
  198. catch (...)
  199. {
  200. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  201. CALL_FAIL (MEM_ERR, TEXT("list::push_back"), dwRes);
  202. PopupError (dwRes);
  203. pServerNode->Destroy ();
  204. return dwRes;
  205. }
  206. pServerNode->AttachFoldersToViews();
  207. pServerNode->RefreshState();
  208. CMainFrame *pFrm = GetFrm();
  209. if (!pFrm)
  210. {
  211. //
  212. // Shutdown in progress
  213. //
  214. return dwRes;
  215. }
  216. CLeftView* pLeftView = pFrm->GetLeftView();
  217. ASSERTION(pLeftView);
  218. CFolderListView* pListView = pLeftView->GetCurrentView();
  219. if(NULL != pListView)
  220. {
  221. //
  222. // refresh current folder
  223. //
  224. FolderType type = pListView->GetType();
  225. CFolder* pFolder = pServerNode->GetFolder(type);
  226. ASSERTION(pFolder);
  227. pFolder->SetVisible();
  228. }
  229. return dwRes;
  230. } // CClientConsoleDoc::AddServerNode
  231. DWORD
  232. CClientConsoleDoc::RefreshServersList()
  233. /*++
  234. Routine name : CClientConsoleDoc::RefreshServersList
  235. Routine description:
  236. Refreshes the list of servers
  237. Author:
  238. Eran Yariv (EranY), Jan, 2000
  239. Arguments:
  240. None.
  241. Return Value:
  242. Standard Win32 error code
  243. --*/
  244. {
  245. DWORD dwRes = ERROR_SUCCESS;
  246. DWORD dwIndex;
  247. PRINTER_INFO_2 *pPrinterInfo2 = NULL;
  248. DWORD dwNumPrinters;
  249. CServerNode* pServerNode;
  250. DBG_ENTER(TEXT("CClientConsoleDoc::RefreshServersList"), dwRes);
  251. //
  252. // Prevent a new servers refresh request
  253. //
  254. if(m_bRefreshingServers )
  255. {
  256. return dwRes;
  257. }
  258. m_bRefreshingServers = TRUE;
  259. if (m_cstrSingleServer.IsEmpty ())
  260. {
  261. SetAllServersInvalid();
  262. //
  263. // Working in a multiple-servers mode (normal mode)
  264. // Enumerate the list of printers available on the system
  265. //
  266. dwRes = GetPrintersInfo(pPrinterInfo2, dwNumPrinters);
  267. if(ERROR_SUCCESS != dwRes)
  268. {
  269. CALL_FAIL (GENERAL_ERR, TEXT("GetPrintersInfo"), dwRes);
  270. goto exit;
  271. }
  272. //
  273. // Iterate the printers
  274. //
  275. for (dwIndex=0; dwIndex < dwNumPrinters; dwIndex++)
  276. {
  277. if(pPrinterInfo2[dwIndex].pDriverName)
  278. {
  279. if (_tcscmp(pPrinterInfo2[dwIndex].pDriverName, FAX_DRIVER_NAME))
  280. {
  281. //
  282. // This printer does not use the Fax Server driver
  283. //
  284. continue;
  285. }
  286. }
  287. //
  288. // Init the node's share and server name
  289. //
  290. if( (NULL == pPrinterInfo2[dwIndex].pShareName ||
  291. 0 == _tcslen(pPrinterInfo2[dwIndex].pShareName)) &&
  292. (NULL == pPrinterInfo2[dwIndex].pServerName ||
  293. 0 == _tcslen(pPrinterInfo2[dwIndex].pServerName)))
  294. {
  295. //
  296. // On Win9x machine, the share name and server name are NULL
  297. // or empty string but the
  298. // port is valid and composed of \\servername\sharename
  299. //
  300. m_bWin9xPrinterFormat = TRUE;
  301. if ((_tcsclen(pPrinterInfo2[dwIndex].pPortName) >= 5) &&
  302. (_tcsncmp(pPrinterInfo2[dwIndex].pPortName, TEXT("\\\\"), 2) == 0))
  303. {
  304. //
  305. // Port name is long enough and starts with "\\"
  306. //
  307. TCHAR* pServerStart = _tcsninc(pPrinterInfo2[dwIndex].pPortName,2);
  308. TCHAR* pShareStart = _tcschr (pServerStart, TEXT('\\'));
  309. if (pShareStart)
  310. {
  311. //
  312. // Share was found after the server name.
  313. // Seperate server from share and advance share name
  314. //
  315. TCHAR* ptcTmp = pShareStart;
  316. pShareStart = _tcsinc(pShareStart);
  317. *ptcTmp = TEXT('\0');
  318. pPrinterInfo2[dwIndex].pShareName = pShareStart;
  319. pPrinterInfo2[dwIndex].pServerName = pServerStart;
  320. }
  321. }
  322. }
  323. pServerNode = FindServerByName(pPrinterInfo2[dwIndex].pServerName);
  324. if(NULL == pServerNode)
  325. {
  326. //
  327. // Create new server node
  328. //
  329. dwRes = AddServerNode (pPrinterInfo2[dwIndex].pServerName);
  330. if (ERROR_SUCCESS != dwRes)
  331. {
  332. CALL_FAIL (GENERAL_ERR, TEXT("AddServerNode"), dwRes);
  333. goto exit;
  334. }
  335. }
  336. else
  337. {
  338. //
  339. // the server node already exists
  340. //
  341. pServerNode->SetValid(TRUE);
  342. }
  343. } // End of printers loop
  344. dwRes = RemoveAllInvalidServers();
  345. if (ERROR_SUCCESS != dwRes)
  346. {
  347. CALL_FAIL (GENERAL_ERR, TEXT("RemoveAllInvalidServers"), dwRes);
  348. goto exit;
  349. }
  350. }
  351. else
  352. {
  353. //
  354. // Working in a single server mode (server name in m_cstrSingleServer).
  355. // Create new server node.
  356. //
  357. int nSize = m_ServersList.size();
  358. ASSERTION(0 == nSize || 1 == nSize);
  359. if(0 == nSize)
  360. {
  361. dwRes = AddServerNode (m_cstrSingleServer);
  362. if (ERROR_SUCCESS != dwRes)
  363. {
  364. CALL_FAIL (GENERAL_ERR, TEXT("AddServerNode"), dwRes);
  365. goto exit;
  366. }
  367. }
  368. else
  369. {
  370. ASSERTION(FindServerByName(m_cstrSingleServer));
  371. }
  372. }
  373. ASSERTION (ERROR_SUCCESS == dwRes);
  374. exit:
  375. SAFE_DELETE_ARRAY (pPrinterInfo2);
  376. //
  377. // Enable a new servers refresh request
  378. //
  379. m_bRefreshingServers = FALSE;
  380. return dwRes;
  381. } // CClientConsoleDoc::RefreshServersList
  382. void CClientConsoleDoc::OnCloseDocument()
  383. {
  384. DBG_ENTER(TEXT("CClientConsoleDoc::OnCloseDocument"));
  385. //
  386. // Signal the event telling all our thread the app. is shutting down
  387. //
  388. SetEvent (m_hShutdownEvent);
  389. m_bShuttingDown = TRUE;
  390. CDocument::OnCloseDocument();
  391. }
  392. void
  393. CClientConsoleDoc::ClearServersList()
  394. /*++
  395. Routine name : CClientConsoleDoc::ClearServersList
  396. Routine description:
  397. Clears the list of servers
  398. Author:
  399. Eran Yariv (EranY), Jan, 2000
  400. Arguments:
  401. Return Value:
  402. None.
  403. --*/
  404. {
  405. DBG_ENTER(TEXT("CClientConsoleDoc::ClearServersList"));
  406. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  407. {
  408. CServerNode *pServerNode = *it;
  409. pServerNode->Destroy ();
  410. }
  411. m_ServersList.clear ();
  412. } // CClientConsoleDoc::ClearServersList
  413. void
  414. CClientConsoleDoc::SetAllServersInvalid()
  415. {
  416. DBG_ENTER(TEXT("CClientConsoleDoc::SetAllServersInvalid"));
  417. CServerNode *pServerNode;
  418. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  419. {
  420. pServerNode = *it;
  421. pServerNode->SetValid(FALSE);
  422. }
  423. }
  424. DWORD
  425. CClientConsoleDoc::RemoveServerNode(
  426. CServerNode* pServer
  427. )
  428. /*++
  429. Routine name : CClientConsoleDoc::RemoveServerNode
  430. Routine description:
  431. remove the server from the servers list and from the tree view
  432. Author:
  433. Alexander Malysh (AlexMay), Mar, 2000
  434. Arguments:
  435. pServer [in] - server node
  436. Return Value:
  437. Standard Win32 error code
  438. --*/
  439. {
  440. DWORD dwRes = ERROR_SUCCESS;
  441. DBG_ENTER(TEXT("CClientConsoleDoc::RemoveServerNode"), dwRes);
  442. ASSERTION(pServer);
  443. dwRes = pServer->InvalidateSubFolders(TRUE);
  444. if(ERROR_SUCCESS != dwRes)
  445. {
  446. CALL_FAIL (GENERAL_ERR, TEXT("CServerNode::InvalidateSubFolders"), dwRes);
  447. return dwRes;
  448. }
  449. //
  450. // remove the server node from the list
  451. //
  452. try
  453. {
  454. m_ServersList.remove(pServer);
  455. }
  456. catch(...)
  457. {
  458. dwRes = ERROR_NOT_ENOUGH_MEMORY;
  459. CALL_FAIL (MEM_ERR, TEXT("list::remove"), dwRes);
  460. return dwRes;
  461. }
  462. //
  463. // delete the server node object
  464. //
  465. pServer->Destroy();
  466. return dwRes;
  467. }
  468. DWORD
  469. CClientConsoleDoc::RemoveAllInvalidServers()
  470. {
  471. DWORD dwRes = ERROR_SUCCESS;
  472. DBG_ENTER(TEXT("CClientConsoleDoc::RemoveAllInvalidServers"), dwRes);
  473. BOOL bSrvFound;
  474. CServerNode *pServerNode;
  475. while(TRUE)
  476. {
  477. //
  478. // find invalid server node
  479. //
  480. bSrvFound = FALSE;
  481. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  482. {
  483. pServerNode = *it;
  484. if(!pServerNode->IsValid())
  485. {
  486. bSrvFound = TRUE;
  487. break;
  488. }
  489. }
  490. if(bSrvFound)
  491. {
  492. //
  493. // remove invalid server node
  494. //
  495. dwRes = RemoveServerNode(pServerNode);
  496. if(ERROR_SUCCESS != dwRes)
  497. {
  498. CALL_FAIL (GENERAL_ERR, TEXT("RemoveServerNode"), dwRes);
  499. break;
  500. }
  501. }
  502. else
  503. {
  504. break;
  505. }
  506. }
  507. return dwRes;
  508. }
  509. CServerNode*
  510. CClientConsoleDoc::FindServerByName(
  511. LPCTSTR lpctstrServer
  512. )
  513. /*++
  514. Routine name : CClientConsoleDoc::FindServerByName
  515. Routine description:
  516. find CServerNode by machine name
  517. Author:
  518. Alexander Malysh (AlexMay), Mar, 2000
  519. Arguments:
  520. lpctstrServer [in] - machine name
  521. Return Value:
  522. CServerNode*
  523. --*/
  524. {
  525. CServerNode *pServerNode = NULL;
  526. CServerNode *pResultNode = NULL;
  527. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  528. {
  529. pServerNode = *it;
  530. if(pServerNode->Machine().Compare(lpctstrServer ? lpctstrServer : TEXT("")) == 0)
  531. {
  532. pResultNode = pServerNode;
  533. break;
  534. }
  535. }
  536. return pResultNode;
  537. }
  538. void
  539. CClientConsoleDoc::SetInvalidFolder(
  540. FolderType type
  541. )
  542. /*++
  543. Routine name : CClientConsoleDoc::InvalidateFolder
  544. Routine description:
  545. invalidate specific folder content
  546. Author:
  547. Alexander Malysh (AlexMay), Apr, 2000
  548. Arguments:
  549. type [in] - folder type
  550. Return Value:
  551. --*/
  552. {
  553. DWORD dwRes = ERROR_SUCCESS;
  554. DBG_ENTER(TEXT("CClientConsoleDoc::InvalidateFolder"));
  555. CFolder* pFolder;
  556. CServerNode* pServerNode;
  557. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  558. {
  559. pServerNode = *it;
  560. pFolder = pServerNode->GetFolder(type);
  561. ASSERTION(pFolder);
  562. if (pFolder)
  563. {
  564. pFolder->SetInvalid();
  565. }
  566. }
  567. }
  568. void
  569. CClientConsoleDoc::ViewFolder(
  570. FolderType type
  571. )
  572. /*++
  573. Routine name : CClientConsoleDoc::ViewFolder
  574. Routine description:
  575. refresh specific folder in all servers
  576. Author:
  577. Alexander Malysh (AlexMay), Apr, 2000
  578. Arguments:
  579. type [in] - folder type
  580. Return Value:
  581. None.
  582. --*/
  583. {
  584. DBG_ENTER(TEXT("CClientConsoleDoc::ViewFolder"));
  585. CFolder* pFolder;
  586. CServerNode *pServerNode;
  587. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  588. {
  589. pServerNode = *it;
  590. pFolder = pServerNode->GetFolder(type);
  591. ASSERTION(pFolder);
  592. pFolder->SetVisible();
  593. }
  594. }
  595. BOOL
  596. CClientConsoleDoc::CanReceiveNow ()
  597. /*++
  598. Routine name : CClientConsoleDoc::CanReceiveNow
  599. Routine description:
  600. Can the user apply the 'Recieve now' option?
  601. Author:
  602. Eran Yariv (EranY), Mar, 2001
  603. Arguments:
  604. Return Value:
  605. TRUE if the user apply the 'Recieve now' option, FALSE otherwise.
  606. --*/
  607. {
  608. BOOL bEnable = FALSE;
  609. //
  610. // Locate the local fax server node
  611. //
  612. CServerNode* pServerNode = FindServerByName (NULL);
  613. if (pServerNode)
  614. {
  615. if(pServerNode->IsOnline() && pServerNode->CanReceiveNow())
  616. {
  617. bEnable = TRUE;
  618. }
  619. }
  620. return bEnable;
  621. } // CClientConsoleDoc::CanReceiveNow
  622. BOOL
  623. CClientConsoleDoc::IsSendFaxEnable()
  624. /*++
  625. Routine name : CClientConsoleDoc::IsSendFaxEnable
  626. Routine description:
  627. does user anable to send fax
  628. Author:
  629. Alexander Malysh (AlexMay), Apr, 2000
  630. Arguments:
  631. Return Value:
  632. TRUE if anable send fax, FALSE otherwise.
  633. --*/
  634. {
  635. BOOL bEnable = FALSE;
  636. CServerNode* pServerNode;
  637. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  638. {
  639. pServerNode = *it;
  640. if(pServerNode->IsOnline() && pServerNode->CanSendFax())
  641. {
  642. bEnable = TRUE;
  643. break;
  644. }
  645. }
  646. return bEnable;
  647. }
  648. int
  649. CClientConsoleDoc::GetFolderDataCount(
  650. FolderType type
  651. )
  652. /*++
  653. Routine name : CClientConsoleDoc::GetFolderDataCount
  654. Routine description:
  655. get total message number in specific folder from all servers
  656. Author:
  657. Alexander Malysh (AlexMay), Apr, 2000
  658. Arguments:
  659. type [in] - folder type
  660. Return Value:
  661. message number
  662. --*/
  663. {
  664. int nCount=0;
  665. CFolder* pFolder;
  666. CServerNode* pServerNode;
  667. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  668. {
  669. pServerNode = *it;
  670. pFolder = pServerNode->GetFolder(type);
  671. nCount += pFolder->GetDataCount();
  672. }
  673. return nCount;
  674. }
  675. BOOL
  676. CClientConsoleDoc::IsFolderRefreshing(
  677. FolderType type
  678. )
  679. /*++
  680. Routine name : CClientConsoleDoc::IsFolderRefreshing
  681. Routine description:
  682. if one of specific folders is refreshing
  683. Author:
  684. Alexander Malysh (AlexMay), Apr, 2000
  685. Arguments:
  686. type [TBD] - folder type
  687. Return Value:
  688. TRUE if one of specific folders is refreshing, FALSE otherwise.
  689. --*/
  690. {
  691. CFolder* pFolder;
  692. CServerNode* pServerNode;
  693. for (SERVERS_LIST::iterator it = m_ServersList.begin(); it != m_ServersList.end(); ++it)
  694. {
  695. pServerNode = *it;
  696. pFolder = pServerNode->GetFolder(type);
  697. if (!pFolder)
  698. {
  699. DBG_ENTER(TEXT("CClientConsoleDoc::IsFolderRefreshing"));
  700. ASSERTION_FAILURE;
  701. }
  702. if(pFolder->IsRefreshing())
  703. {
  704. return TRUE;
  705. }
  706. }
  707. return FALSE;
  708. }