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.

597 lines
17 KiB

  1. /*======================================================================================//
  2. | Process Control //
  3. | //
  4. |Copyright (c) 1998 Sequent Computer Systems, Incorporated. All rights reserved. //
  5. | //
  6. |File Name: ProcessRuleFolder.cpp //
  7. | //
  8. |Description: Implementation of process rule node //
  9. | //
  10. |Created: Paul Skoglund 09-1998 //
  11. | //
  12. |Rev History: //
  13. | //
  14. |=======================================================================================*/
  15. #include "StdAfx.h"
  16. #include "BaseNode.h"
  17. #include "ManagementPages.h"
  18. #include "ManagementRuleWizards.h"
  19. #include "ProcessPages.h"
  20. #pragma warning(push)
  21. #include <algorithm>
  22. #pragma warning(pop)
  23. using std::find;
  24. using std::list<PCProcSummary*>;
  25. const GUID CProcessRuleFolder::m_GUID = {0xff9baf65,0x064e,0x11d2,{0x80, 0x14,0x00,0x10,0x4b,0x9a,0x31,0x06} };
  26. const TCHAR *const CProcessRuleFolder::m_szGUID = _T("{ff9baf65-064e-11d2-8014-00104b9a3106}");
  27. // Array of view items to be inserted into the context menu.
  28. const CONTEXTMENUITEMBYID CProcessRuleFolder::TopMenuItems[] =
  29. {
  30. { IDS_PRULE_TOP, ID_PRULE_NEW, ID_PRULE_NEW, CCM_INSERTIONPOINTID_PRIMARY_TOP },
  31. { 0, 0, 0, 0 }
  32. };
  33. const CONTEXTMENUITEMBYID CProcessRuleFolder::NewMenuItems[] =
  34. {
  35. { IDS_PRULE_NEW, ID_PRULE_NEW, ID_PRULE_NEW, CCM_INSERTIONPOINTID_PRIMARY_NEW },
  36. { 0, 0, 0, 0 }
  37. };
  38. CProcessRuleFolder::CProcessRuleFolder(CBaseNode *pParent) : CBaseNode(PROCESSRULE_NODE, pParent), m_ID(0)
  39. {
  40. LoadStringHelper(m_name, IDS_PROCESSRULE_FOLDER);
  41. }
  42. CProcessRuleFolder::~CProcessRuleFolder()
  43. {
  44. ClearCache();
  45. ATLTRACE( _T("~CProcessRuleFolder end\n"));
  46. }
  47. LPCTSTR CProcessRuleFolder::GetNodeName()
  48. {
  49. return m_name;
  50. }
  51. HRESULT CProcessRuleFolder::GetDisplayInfo(RESULTDATAITEM &ResultItem)
  52. {
  53. if (ResultItem.bScopeItem)
  54. {
  55. if( ResultItem.mask & RDI_STR )
  56. {
  57. if (0 == ResultItem.nCol)
  58. ResultItem.str = const_cast<LPOLESTR>(GetNodeName());
  59. else
  60. ResultItem.str = _T("");
  61. }
  62. if (ResultItem.mask & RDI_IMAGE)
  63. ResultItem.nImage = sImage();
  64. return S_OK;
  65. }
  66. list<PCProcSummary*>::iterator item;
  67. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcSummary*>(ResultItem.lParam) );
  68. if (item == Cache.end() )
  69. return E_UNEXPECTED;
  70. if (ResultItem.mask & RDI_IMAGE)
  71. ResultItem.nImage = PROCESSRULEITEMIMAGE;
  72. if (ResultItem.mask & RDI_STR)
  73. {
  74. PCProcSummary &ref = **item;
  75. LPCTSTR &pstr = ResultItem.str;
  76. switch (ResultItem.nCol)
  77. {
  78. case PROCESS_ALIAS_COLUMN:
  79. pstr = ref.procName;
  80. break;
  81. case DESCRIPTION_COLUMN:
  82. pstr = ref.mgmtParms.description;
  83. break;
  84. case APPLY_JOB_COLUMN:
  85. pstr = FormatApplyFlag(m_ResultStr, ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP);
  86. break;
  87. case JOB_COLUMN:
  88. pstr = ref.memberOfJobName;
  89. break;
  90. case APPLY_AFFINITY_COLUMN:
  91. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  92. pstr = _T("");
  93. else
  94. pstr = FormatApplyFlag(m_ResultStr, ref.mgmtParms.mFlags & PCMFLAG_APPLY_AFFINITY);
  95. break;
  96. case AFFINITY_COLUMN:
  97. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  98. pstr = _T("");
  99. else
  100. pstr = FormatAffinity(m_ResultStr, ref.mgmtParms.affinity);
  101. break;
  102. case APPLY_PRIORITY_COLUMN:
  103. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  104. pstr = _T("");
  105. else
  106. pstr = FormatApplyFlag(m_ResultStr, ref.mgmtParms.mFlags & PCMFLAG_APPLY_PRIORITY);
  107. break;
  108. case PRIORITY_COLUMN:
  109. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  110. pstr = _T("");
  111. else
  112. pstr = FormatPriority(m_ResultStr, ref.mgmtParms.priority);
  113. break;
  114. case APPLY_MINMAXWS_COLUMN:
  115. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  116. pstr = _T("");
  117. else
  118. pstr = FormatApplyFlag(m_ResultStr, ref.mgmtParms.mFlags & PCMFLAG_APPLY_WS_MINMAX);
  119. break;
  120. case MINWS_COLUMN:
  121. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  122. pstr = _T("");
  123. else
  124. pstr = FormatMemory(m_ResultStr, ref.mgmtParms.minWS);
  125. break;
  126. case MAXWS_COLUMN:
  127. if (ref.mgmtParms.mFlags & PCMFLAG_APPLY_JOB_MEMBERSHIP)
  128. pstr = _T("");
  129. else
  130. pstr = FormatMemory(m_ResultStr, ref.mgmtParms.maxWS);
  131. break;
  132. default:
  133. ASSERT(FALSE);
  134. pstr = _T("");
  135. break;
  136. }
  137. }
  138. return S_OK;
  139. }
  140. HRESULT CProcessRuleFolder::OnShow(BOOL bSelecting, HSCOPEITEM hItem, IHeaderCtrl2 *ipHeaderCtrl, IConsole2 *ipConsole2)
  141. {
  142. ASSERT(hItem == GetID());
  143. if (!bSelecting)
  144. return S_OK;
  145. ITEM_STR str;
  146. LoadStringHelper(str, IDS_PROCESS_ALIAS_HDR);
  147. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PROCESS_ALIAS_COLUMN, str, 0, PROCESS_ALIAS_COLUMN_WIDTH ));
  148. LoadStringHelper(str, IDS_DESCRIPTION_HDR);
  149. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( DESCRIPTION_COLUMN, str, 0, DESCRIPTION_COLUMN_WIDTH ));
  150. LoadStringHelper(str, IDS_APPLY_JOB_HDR);
  151. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( APPLY_JOB_COLUMN, str, 0, APPLY_JOB_COLUMN_WIDTH ));
  152. LoadStringHelper(str, IDS_JOB_HDR);
  153. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( JOB_COLUMN, str, 0, JOB_COLUMN_WIDTH ));
  154. LoadStringHelper(str, IDS_APPLY_AFFINITY_HDR);
  155. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( APPLY_AFFINITY_COLUMN, str, 0, APPLY_AFFINITY_COLUMN_WIDTH ));
  156. LoadStringHelper(str, IDS_AFFINITY_HDR);
  157. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( AFFINITY_COLUMN, str, 0, AFFINITY_COLUMN_WIDTH ));
  158. LoadStringHelper(str, IDS_APPLY_PRIORITY_HDR);
  159. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( APPLY_PRIORITY_COLUMN, str, 0, APPLY_PRIORITY_COLUMN_WIDTH ));
  160. LoadStringHelper(str, IDS_PRIORITY_HDR);
  161. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( PRIORITY_COLUMN, str, 0, PRIORITY_COLUMN_WIDTH ));
  162. LoadStringHelper(str, IDS_APPLY_MINMAXWS_HDR);
  163. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( APPLY_MINMAXWS_COLUMN, str, 0, APPLY_MINMAXWS_COLUMN_WIDTH ));
  164. LoadStringHelper(str, IDS_MINWS_HDR);
  165. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( MINWS_COLUMN, str, 0, MINWS_COLUMN_WIDTH ));
  166. LoadStringHelper(str, IDS_MAXWS_HDR);
  167. VERIFY(S_OK == ipHeaderCtrl->InsertColumn( MAXWS_COLUMN, str, 0, MAXWS_COLUMN_WIDTH ));
  168. return OnRefresh(ipConsole2);
  169. }
  170. HRESULT CProcessRuleFolder::AddMenuItems(LPCONTEXTMENUCALLBACK piCallback, long * pInsertionAllowed)
  171. {
  172. HRESULT hr = S_OK;
  173. ITEM_STR name;
  174. ITEM_STR status;
  175. BOOL bConnected = GetPCid();
  176. CONTEXTMENUITEM m = { 0 };
  177. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP)
  178. {
  179. for (const CONTEXTMENUITEMBYID *M = TopMenuItems; M->lCommandID; M++)
  180. {
  181. m.strName = const_cast<TCHAR *>(LoadStringHelper(name, M->strNameID));
  182. m.strStatusBarText = const_cast<TCHAR *>(LoadStringHelper(status, M->strStatusBarTextID));
  183. m.lCommandID = M->lCommandID;
  184. m.lInsertionPointID = M->lInsertionPointID;
  185. m.fFlags = bConnected ? MF_ENABLED : MF_GRAYED;
  186. //m.fSpecialFlags = 0; // currently always 0, initialized to 0
  187. hr = piCallback->AddItem(&m);
  188. if (FAILED(hr))
  189. break;
  190. }
  191. }
  192. if (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW )
  193. {
  194. for (const CONTEXTMENUITEMBYID *M = NewMenuItems; M->lCommandID; M++)
  195. {
  196. m.strName = const_cast<TCHAR *>(LoadStringHelper(name, M->strNameID));
  197. m.strStatusBarText = const_cast<TCHAR *>(LoadStringHelper(status, M->strStatusBarTextID));
  198. m.lCommandID = M->lCommandID;
  199. m.lInsertionPointID = M->lInsertionPointID;
  200. m.fFlags = bConnected ? MF_ENABLED : MF_GRAYED;
  201. //m.fSpecialFlags = 0; // currently always 0, initialized to 0
  202. hr = piCallback->AddItem(&m);
  203. if (FAILED(hr))
  204. break;
  205. }
  206. }
  207. return hr;
  208. }
  209. HRESULT CProcessRuleFolder::OnHelpCmd(IDisplayHelp *ipDisplayHelp)
  210. {
  211. if (!ipDisplayHelp)
  212. return E_UNEXPECTED;
  213. ipDisplayHelp->ShowTopic(const_cast<TCHAR *>(HELP_ru_proc));
  214. return S_OK;
  215. }
  216. HRESULT CProcessRuleFolder::OnSelect(BOOL bScope, BOOL bSelect, IConsoleVerb* ipConsoleVerb)
  217. {
  218. ASSERT(bScope);
  219. if ( bSelect )
  220. {
  221. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE ) == S_OK);
  222. VERIFY( ipConsoleVerb->SetDefaultVerb( MMC_VERB_OPEN ) == S_OK );
  223. }
  224. return S_OK;
  225. }
  226. HRESULT CProcessRuleFolder::OnSelect(BOOL bScope, BOOL bSelect, IConsoleVerb* ipConsoleVerb, LPARAM Cookie)
  227. {
  228. ASSERT(!bScope);
  229. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_REFRESH, ENABLED, TRUE ) == S_OK);
  230. if (bSelect && !bScope) // incase the rules are changed again leave !bScope test
  231. {
  232. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_PROPERTIES, ENABLED, TRUE ) == S_OK);
  233. VERIFY( ipConsoleVerb->SetVerbState( MMC_VERB_DELETE, ENABLED, TRUE ) == S_OK);
  234. VERIFY( ipConsoleVerb->SetDefaultVerb( MMC_VERB_PROPERTIES ) == S_OK );
  235. }
  236. return S_OK;
  237. }
  238. HRESULT CProcessRuleFolder::OnMenuCommand(IConsole2 *ipConsole2, long nCommandID )
  239. {
  240. HRESULT hr = S_FALSE;
  241. switch(nCommandID)
  242. {
  243. case ID_PRULE_NEW:
  244. {
  245. PCid hID = GetPCid();
  246. PCSystemInfo SystemInfo;
  247. if (!hID || !PCGetServiceInfo(hID, &SystemInfo, sizeof(SystemInfo)))
  248. {
  249. ReportPCError();
  250. return S_OK;
  251. }
  252. PCProcSummary *ptr = new PCProcSummary[1];
  253. if (!ptr)
  254. return E_UNEXPECTED;
  255. PCProcDetail ProcDetail = { 0 };
  256. list<tstring> jobs;
  257. VERIFY( GetGrpNameList(hID, jobs) );
  258. if (ProcRuleWizard(IDS_PRULE_CREATE_TITLE, jobs, ProcDetail, SystemInfo.sysParms, NULL) )
  259. {
  260. if (PCAddProcDetail(hID, &ProcDetail) )
  261. {
  262. *ptr = ProcDetail.base;
  263. MemBlocks.push_front(ptr);
  264. Cache.push_front(ptr);
  265. VERIFY(S_OK == SendViewChange(ipConsole2, (INT_PTR) ptr, PC_VIEW_ADDITEM));
  266. return S_OK;
  267. }
  268. ReportPCError();
  269. }
  270. delete [] ptr;
  271. }
  272. return S_OK; // we handled the message...
  273. default:
  274. break;
  275. }
  276. return hr;
  277. }
  278. HRESULT CProcessRuleFolder::OnMenuCommand(IConsole2 *ipConsole2, long nCommandID, LPARAM Cookie )
  279. {
  280. return OnMenuCommand(ipConsole2, nCommandID);
  281. }
  282. HRESULT CProcessRuleFolder::OnViewChange(IResultData *ipResultData, LPARAM thing, LONG_PTR hint)
  283. {
  284. ASSERT(ipResultData);
  285. if (!ipResultData)
  286. return E_UNEXPECTED;
  287. VERIFY(ipResultData->ModifyViewStyle(MMC_SINGLESEL, MMC_NOSORTHEADER) == S_OK);
  288. list<PCProcSummary*>::iterator item;
  289. HRESULT hr = E_UNEXPECTED;
  290. switch (hint)
  291. {
  292. case PC_VIEW_REDRAWALL:// not currently used
  293. hr = ShowAllItems(ipResultData, TRUE);
  294. break;
  295. case PC_VIEW_SETITEM: // not currently used
  296. ASSERT(FALSE); // add smarter support for this hint...
  297. hr = ShowAllItems(ipResultData, TRUE);
  298. break;
  299. case PC_VIEW_UPDATEALL:
  300. hr = ShowAllItems(ipResultData, FALSE);
  301. break;
  302. case PC_VIEW_UPDATEITEM:
  303. {
  304. HRESULTITEM hItem;
  305. hr = ipResultData->FindItemByLParam(thing, &hItem);
  306. if (hr == S_OK)
  307. hr = ipResultData->UpdateItem(hItem);
  308. }
  309. break;
  310. case PC_VIEW_ADDITEM:
  311. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcSummary*>(thing) );
  312. if (item == Cache.end())
  313. hr = E_UNEXPECTED;
  314. else
  315. {
  316. RESULTDATAITEM data = { 0 };
  317. data.mask = RDI_STR | RDI_IMAGE | RDI_PARAM | RDI_STATE;
  318. data.bScopeItem = FALSE;
  319. //data.itemID
  320. //data.nIndex
  321. //data.nCol
  322. data.str = (LPOLESTR)MMC_CALLBACK;
  323. data.nImage = PROCESSRULEITEMIMAGE;
  324. //data.nState
  325. //data.iIndent //reserved
  326. data.lParam = thing;
  327. //data.nState
  328. hr = ipResultData->InsertItem(&data);
  329. }
  330. break;
  331. case PC_VIEW_DELETEITEM:
  332. {
  333. HRESULTITEM hItem;
  334. hr = ipResultData->FindItemByLParam(thing, &hItem);
  335. if (hr == S_OK)
  336. hr = ipResultData->DeleteItem(hItem, 0);
  337. }
  338. break;
  339. default:
  340. hr = E_UNEXPECTED;
  341. break;
  342. }
  343. ASSERT(hr == S_OK);
  344. return hr;
  345. }
  346. HRESULT CProcessRuleFolder::ShowAllItems(IResultData* ipResultData, BOOL bCacheValid)
  347. {
  348. list<PCProcSummary*>::iterator item;
  349. LPARAM selected = 0;
  350. LPARAM focused = 0;
  351. RESULTDATAITEM data;
  352. if (bCacheValid)
  353. {
  354. memset(&data, 0, sizeof(data));
  355. data.nIndex = -1;
  356. data.nState = LVIS_SELECTED;
  357. data.mask = RDI_STATE;
  358. if (S_OK == ipResultData->GetNextItem(&data) && data.nIndex != -1 )
  359. {
  360. selected = data.lParam;
  361. }
  362. memset(&data, 0, sizeof(data));
  363. data.nIndex = -1;
  364. data.nState = LVIS_FOCUSED;
  365. data.mask = RDI_STATE;
  366. if (S_OK == ipResultData->GetNextItem(&data) && data.nIndex != -1)
  367. {
  368. focused = data.lParam;
  369. }
  370. }
  371. ipResultData->DeleteAllRsltItems();
  372. memset(&data, 0, sizeof(data));
  373. data.mask = RDI_STR | RDI_IMAGE | RDI_PARAM | RDI_STATE;
  374. data.bScopeItem = FALSE;
  375. //data.itemID;
  376. data.nIndex = 0;
  377. data.nCol = 0;
  378. data.str = (LPOLESTR)MMC_CALLBACK;
  379. data.nImage = PROCESSRULEITEMIMAGE;
  380. data.nState = 0;
  381. data.iIndent = 0; //reserved
  382. HRESULT hr = S_OK;
  383. for (list<PCProcSummary*>::iterator i = Cache.begin(); i != Cache.end(); ++i)
  384. {
  385. data.lParam = reinterpret_cast<LPARAM>(*i);
  386. data.nState = 0;
  387. if (data.lParam == selected)
  388. data.nState |= LVIS_SELECTED;
  389. if (data.lParam == focused)
  390. data.nState |= LVIS_FOCUSED;
  391. hr = ipResultData->InsertItem(&data);
  392. if (hr != S_OK)
  393. break;
  394. }
  395. return hr;
  396. }
  397. void CProcessRuleFolder::ClearCache()
  398. {
  399. Cache.clear();
  400. for (list<PCProcSummary*>::iterator chunck = MemBlocks.begin(); chunck != MemBlocks.end(); ++chunck)
  401. {
  402. delete [] (*chunck);
  403. }
  404. MemBlocks.clear();
  405. }
  406. BOOL CProcessRuleFolder::RefreshCache()
  407. {
  408. PCINT32 res = 0;
  409. PCULONG32 err = 0;
  410. PCProcSummary *last = NULL;
  411. const int MINIMUM_ALLOCATION = min((COM_BUFFER_SIZE/sizeof(PCProcSummary)), 100);
  412. ClearCache();
  413. PCid hID = GetPCid();
  414. if (!hID)
  415. {
  416. ReportPCError();
  417. return false;
  418. }
  419. do
  420. {
  421. PCProcSummary *ptr = new PCProcSummary[MINIMUM_ALLOCATION];
  422. if (!ptr)
  423. {
  424. err = ERROR_OUTOFMEMORY;
  425. break;
  426. }
  427. if (last)
  428. memcpy(ptr, last, sizeof(PCProcSummary));
  429. else
  430. memset(ptr, 0, sizeof(PCProcSummary));
  431. res = PCGetProcSummary( hID, ptr, MINIMUM_ALLOCATION * sizeof(PCProcSummary));
  432. if (res < 0 )
  433. {
  434. err = GetLastPCError();
  435. delete [] ptr;
  436. break;
  437. }
  438. if (res > 0)
  439. {
  440. last = &ptr[res - 1];
  441. MemBlocks.push_front(ptr);
  442. for (INT32 i = 0; i < res; i++)
  443. {
  444. Cache.insert(Cache.end(), ptr);
  445. ptr++;
  446. }
  447. }
  448. } while (res > 0 && PCERROR_MORE_DATA == GetLastPCError() );
  449. if (err)
  450. ReportPCError();
  451. return err == 0;
  452. }
  453. HRESULT CProcessRuleFolder::QueryPagesFor(LPARAM Cookie)
  454. {
  455. list<PCProcSummary*>::iterator item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcSummary*>(Cookie) );
  456. if (item != Cache.end() )
  457. return S_OK;
  458. return E_UNEXPECTED;
  459. }
  460. HRESULT CProcessRuleFolder::OnCreatePropertyPages( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle, DATA_OBJECT_TYPES context, LPARAM Cookie)
  461. {
  462. list<PCProcSummary*>::iterator item;
  463. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcSummary*>(Cookie) );
  464. if (item == Cache.end() )
  465. return E_UNEXPECTED;
  466. return CreatePropertyPagesForProcDetail( (*item)->procName, lpProvider, handle, this );
  467. }
  468. HRESULT CProcessRuleFolder::OnPropertyChange(PROPERTY_CHANGE_HDR *pUpdate, IConsole2 *ipConsole2)
  469. {
  470. return OnRefresh(ipConsole2);
  471. }
  472. HRESULT CProcessRuleFolder::OnDelete(IConsole2 *ipConsole2, LPARAM Cookie)
  473. {
  474. list<PCProcSummary*>::iterator item;
  475. item = find(Cache.begin(), Cache.end(), reinterpret_cast<PCProcSummary*>(Cookie) );
  476. if ( item == Cache.end() )
  477. {
  478. SendViewChange(ipConsole2, NULL, PC_VIEW_UPDATEALL);
  479. return E_UNEXPECTED;
  480. }
  481. PCProcDetail Detail;
  482. memset(&Detail, 0, sizeof(Detail));
  483. memcpy(&(Detail.base), (*item), sizeof(PCProcSummary) );
  484. if (!PCDeleteProcDetail(GetPCid(), &Detail))
  485. {
  486. ReportPCError();
  487. return E_UNEXPECTED;
  488. }
  489. Cache.erase(item);
  490. return SendViewChange(ipConsole2, Cookie, PC_VIEW_DELETEITEM);
  491. }
  492. HRESULT CProcessRuleFolder::OnRefresh(IConsole2 *ipConsole2)
  493. {
  494. RefreshCache();
  495. return SendViewChange(ipConsole2, NULL, PC_VIEW_UPDATEALL);
  496. }