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.

2940 lines
92 KiB

  1. /*******************************************************************************
  2. *
  3. * domainpg.cpp
  4. *
  5. * implementations of the Domain info pages
  6. *
  7. * copyright notice: Copyright 1997, Citrix Systems Inc.
  8. * Copyright (c) 1998 - 1999 Microsoft Corporation
  9. *
  10. * $Author: donm $ Don Messerli
  11. *
  12. * $Log: N:\nt\private\utils\citrix\winutils\tsadmin\VCS\domainpg.cpp $
  13. *
  14. * Rev 1.2 19 Feb 1998 17:40:30 donm
  15. * removed latest extension DLL support
  16. *
  17. * Rev 1.1 19 Jan 1998 16:47:36 donm
  18. * new ui behavior for domains and servers
  19. *
  20. * Rev 1.0 03 Nov 1997 15:07:22 donm
  21. * Initial revision.
  22. *
  23. *******************************************************************************/
  24. #include "stdafx.h"
  25. #include "winadmin.h"
  26. #include "admindoc.h"
  27. #include "domainpg.h"
  28. #include <malloc.h> // for alloca used by Unicode conversion macros
  29. #include <mfc42\afxconv.h> // for Unicode conversion macros
  30. //USES_CONVERSION
  31. static int _convert;
  32. #ifdef _DEBUG
  33. #define new DEBUG_NEW
  34. #undef THIS_FILE
  35. static char THIS_FILE[] = __FILE__;
  36. #endif
  37. ////////////////////////////////
  38. // MESSAGE MAP: CDomainServersPage
  39. //
  40. IMPLEMENT_DYNCREATE(CDomainServersPage, CFormView)
  41. BEGIN_MESSAGE_MAP(CDomainServersPage, CFormView)
  42. //{{AFX_MSG_MAP(CDomainServersPage)
  43. ON_WM_SIZE()
  44. ON_NOTIFY(LVN_COLUMNCLICK, IDC_SERVER_LIST, OnColumnclick)
  45. ON_WM_CONTEXTMENU()
  46. ON_NOTIFY(LVN_ITEMCHANGED, IDC_SERVER_LIST, OnServerItemChanged)
  47. ON_NOTIFY(NM_SETFOCUS, IDC_SERVER_LIST, OnSetfocusServerList)
  48. //ON_NOTIFY(NM_KILLFOCUS, IDC_SERVER_LIST, OnKillfocusServerList)
  49. //}}AFX_MSG_MAP
  50. END_MESSAGE_MAP()
  51. /////////////////////////////
  52. // F'N: CDomainServersPage ctor
  53. //
  54. CDomainServersPage::CDomainServersPage()
  55. : CAdminPage(CDomainServersPage::IDD)
  56. {
  57. //{{AFX_DATA_INIT(CDomainServersPage)
  58. // NOTE: the ClassWizard will add member initialization here
  59. //}}AFX_DATA_INIT
  60. m_pDomain = NULL;
  61. m_bSortAscending = TRUE;
  62. } // end CDomainServersPage ctor
  63. /////////////////////////////
  64. // F'N: CDomainServersPage dtor
  65. //
  66. CDomainServersPage::~CDomainServersPage()
  67. {
  68. } // end CDomainServersPage dtor
  69. ////////////////////////////////////////
  70. // F'N: CDomainServersPage::DoDataExchange
  71. //
  72. void CDomainServersPage::DoDataExchange(CDataExchange* pDX)
  73. {
  74. CFormView::DoDataExchange(pDX);
  75. //{{AFX_DATA_MAP(CDomainServersPage)
  76. DDX_Control(pDX, IDC_SERVER_LIST, m_ServerList);
  77. //}}AFX_DATA_MAP
  78. } // end CDomainServersPage::DoDataExchange
  79. #ifdef _DEBUG
  80. /////////////////////////////////////
  81. // F'N: CDomainServersPage::AssertValid
  82. //
  83. void CDomainServersPage::AssertValid() const
  84. {
  85. CFormView::AssertValid();
  86. } // end CDomainServersPage::AssertValid
  87. //////////////////////////////
  88. // F'N: CDomainServersPage::Dump
  89. //
  90. void CDomainServersPage::Dump(CDumpContext& dc) const
  91. {
  92. CFormView::Dump(dc);
  93. } // end CDomainServersPage::Dump
  94. #endif //_DEBUG
  95. //////////////////////////////
  96. // F'N: CDomainServersPage::OnSize
  97. //
  98. void CDomainServersPage::OnSize(UINT nType, int cx, int cy)
  99. {
  100. RECT rect;
  101. GetClientRect(&rect);
  102. rect.top += LIST_TOP_OFFSET;
  103. if(m_ServerList.GetSafeHwnd())
  104. m_ServerList.MoveWindow(&rect, TRUE);
  105. // CFormView::OnSize(nType, cx, cy);
  106. } // end CDomainServersPage::OnSize
  107. static ColumnDef ServerColumns[] = {
  108. CD_SERVER,
  109. CD_TCPADDRESS,
  110. CD_IPXADDRESS,
  111. CD_NUM_SESSIONS
  112. };
  113. #define NUM_DOMAIN_SERVER_COLUMNS sizeof(ServerColumns)/sizeof(ColumnDef)
  114. //////////////////////////////
  115. // F'N: CDomainServersPage::OnInitialUpdate
  116. //
  117. void CDomainServersPage::OnInitialUpdate()
  118. {
  119. CFormView::OnInitialUpdate();
  120. BuildImageList(); // builds the image list for the list control
  121. CString columnString;
  122. for(int col = 0; col < NUM_DOMAIN_SERVER_COLUMNS; col++) {
  123. columnString.LoadString(ServerColumns[col].stringID);
  124. m_ServerList.InsertColumn(col, columnString, ServerColumns[col].format, ServerColumns[col].width, col);
  125. }
  126. m_CurrentSortColumn = SERVERS_COL_SERVER;
  127. } // end CDomainServersPage::OnInitialUpdate
  128. /////////////////////////////////////
  129. // F'N: CDomainServersPage::BuildImageList
  130. //
  131. // - calls m_ImageList.Create(..) to create the image list
  132. // - calls AddIconToImageList(..) to add the icons themselves and save
  133. // off their indices
  134. // - attaches the image list to the list ctrl
  135. //
  136. void CDomainServersPage::BuildImageList()
  137. {
  138. m_ImageList.Create(16, 16, TRUE, 4, 0);
  139. m_idxServer = AddIconToImageList(IDI_SERVER);
  140. m_idxCurrentServer = AddIconToImageList(IDI_CURRENT_SERVER);
  141. m_idxNotSign = AddIconToImageList(IDI_NOTSIGN);
  142. m_idxQuestion = AddIconToImageList(IDI_QUESTIONMARK);
  143. m_ImageList.SetOverlayImage(m_idxNotSign, 1);
  144. m_ImageList.SetOverlayImage(m_idxQuestion, 2);
  145. m_ServerList.SetImageList(&m_ImageList, LVSIL_SMALL);
  146. } // end CDomainServersPage::BuildImageList
  147. /////////////////////////////////////////
  148. // F'N: CDomainServersPage::AddIconToImageList
  149. //
  150. // - loads the appropriate icon, adds it to m_ImageList, and returns
  151. // the newly-added icon's index in the image list
  152. //
  153. int CDomainServersPage::AddIconToImageList(int iconID)
  154. {
  155. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  156. return m_ImageList.Add(hIcon);
  157. } // end CDomainServersPage::AddIconToImageList
  158. //////////////////////////////
  159. // F'N: CDomainServersPage::Reset
  160. //
  161. void CDomainServersPage::Reset(void *pDomain)
  162. {
  163. ASSERT(pDomain);
  164. m_pDomain = (CDomain*)pDomain;
  165. DisplayServers();
  166. } // end CDomainServersPage::Reset
  167. //////////////////////////////
  168. // F'N: CDomainServersPage::AddServer
  169. //
  170. void CDomainServersPage::AddServer(CServer *pServer)
  171. {
  172. ASSERT(pServer);
  173. // We have to make sure the server isn't already in the list
  174. // Add the server to the list
  175. if(AddServerToList(pServer)) {
  176. // Tell the list to sort itself
  177. LockListControl();
  178. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_SERVERS, &m_ServerList, m_CurrentSortColumn, m_bSortAscending);
  179. UnlockListControl();
  180. }
  181. } // end CDomainServersPage::AddServer
  182. //////////////////////////////
  183. // F'N: CDomainServersPage::RemoveServer
  184. //
  185. void CDomainServersPage::RemoveServer(CServer *pServer)
  186. {
  187. ASSERT(pServer);
  188. // If the server isn't in the current domain, there's nothing to do
  189. if(m_pDomain != pServer->GetDomain()) return;
  190. LockListControl();
  191. // Find out how many items in the list
  192. int ItemCount = m_ServerList.GetItemCount();
  193. // Go through the items are remove this server
  194. for(int item = 0; item < ItemCount; item++) {
  195. CServer *pListServer = (CServer*)m_ServerList.GetItemData(item);
  196. if(pListServer == pServer) {
  197. m_ServerList.DeleteItem(item);
  198. pServer->ClearAllSelected();
  199. break;
  200. }
  201. }
  202. UnlockListControl();
  203. } // end CDomainServersPage::RemoveServer
  204. //////////////////////////////
  205. // F'N: CDomainServersPage::UpdateServer
  206. //
  207. void CDomainServersPage::UpdateServer(CServer *pServer)
  208. {
  209. ASSERT(pServer);
  210. // If the server isn't in the current domain, there's nothing to do
  211. if(m_pDomain != pServer->GetDomain()) return;
  212. // If we aren't connected to the server anymore, remove it from the list control
  213. if(pServer->IsState(SS_NOT_CONNECTED)) {
  214. RemoveServer(pServer);
  215. return;
  216. }
  217. // If we just connected to this server, add it to the list control
  218. if(pServer->IsState(SS_GOOD)) {
  219. AddServer(pServer);
  220. return;
  221. }
  222. LockListControl();
  223. // Find the Server in the list
  224. LV_FINDINFO FindInfo;
  225. FindInfo.flags = LVFI_PARAM;
  226. FindInfo.lParam = (LPARAM)pServer;
  227. // Find the Server in our list
  228. int item = m_ServerList.FindItem(&FindInfo, -1);
  229. if(item != -1) {
  230. // Change the icon overlay
  231. USHORT NewState;
  232. // Change the icon/overlay for the server
  233. // If the server isn't sane, put a not sign over the icon
  234. if(!pServer->IsServerSane()) NewState = STATE_NOT;
  235. // If we aren't done getting all the information about this server,
  236. // put a question mark over the icon
  237. else if(!pServer->IsState(SS_GOOD)) NewState = STATE_QUESTION;
  238. // If it is fine, we want to remove any overlays from the icon
  239. else NewState = STATE_NORMAL;
  240. // Set the tree item to the new state
  241. m_ServerList.SetItemState(item, NewState, 0x0F00);
  242. ExtServerInfo *pExtServerInfo = pServer->GetExtendedInfo();
  243. // TCP Address
  244. m_ServerList.SetItemText(item, SERVERS_COL_TCPADDRESS, pExtServerInfo->TcpAddress);
  245. // IPX Address
  246. m_ServerList.SetItemText(item, SERVERS_COL_IPXADDRESS, pExtServerInfo->IpxAddress);
  247. CString NumString;
  248. if(pExtServerInfo && (pExtServerInfo->Flags & ESF_WINFRAME)) {
  249. NumString.Format(TEXT("%lu"), pExtServerInfo->ServerTotalInUse);
  250. } else {
  251. NumString.LoadString(IDS_NOT_APPLICABLE);
  252. }
  253. m_ServerList.SetItemText(item, SERVERS_COL_NUMWINSTATIONS, NumString);
  254. }
  255. // Tell the list to sort itself
  256. if(m_CurrentSortColumn == SERVERS_COL_NUMWINSTATIONS
  257. || m_CurrentSortColumn == SERVERS_COL_TCPADDRESS
  258. || m_CurrentSortColumn == SERVERS_COL_IPXADDRESS)
  259. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_SERVERS, &m_ServerList, m_CurrentSortColumn, m_bSortAscending);
  260. UnlockListControl();
  261. } // end CDomainServersPage::UpdateServer
  262. //////////////////////////////
  263. // F'N: CDomainServersPage::AddServerToList
  264. //
  265. BOOL CDomainServersPage::AddServerToList(CServer *pServer)
  266. {
  267. ASSERT(pServer);
  268. // If the server isn't in the current domain, there's nothing to do
  269. if(m_pDomain != pServer->GetDomain()) return FALSE;
  270. // If we aren't currently connected to the server, don't display it
  271. if(!pServer->IsState(SS_GOOD)) return FALSE;
  272. LockListControl();
  273. // Find the Server in the list
  274. LV_FINDINFO FindInfo;
  275. FindInfo.flags = LVFI_PARAM;
  276. FindInfo.lParam = (LPARAM)pServer;
  277. // Find the Server in our list
  278. int item = m_ServerList.FindItem(&FindInfo, -1);
  279. if(item != -1) return FALSE;
  280. //////////////////////
  281. // Fill in the columns
  282. //////////////////////
  283. // Name - put at the end of the list
  284. item = m_ServerList.InsertItem(m_ServerList.GetItemCount(), pServer->GetName(),
  285. pServer->IsCurrentServer() ? m_idxCurrentServer : m_idxServer);
  286. // If the server isn't sane, put a not sign over the icon
  287. if(!pServer->IsServerSane()) m_ServerList.SetItemState(item, STATE_NOT, 0x0F00);
  288. // If we aren't done getting all the information about this server,
  289. // put a question mark over the icon
  290. else if(!pServer->IsState(SS_GOOD)) m_ServerList.SetItemState(item, STATE_QUESTION, 0x0F00);
  291. ExtServerInfo *pExtServerInfo = pServer->GetExtendedInfo();
  292. // TCP Address
  293. m_ServerList.SetItemText(item, SERVERS_COL_TCPADDRESS, pExtServerInfo->TcpAddress);
  294. // IPX Address
  295. m_ServerList.SetItemText(item, SERVERS_COL_IPXADDRESS, pExtServerInfo->IpxAddress);
  296. // Connected
  297. CString NumString;
  298. if(pExtServerInfo && (pExtServerInfo->Flags & ESF_WINFRAME)) {
  299. NumString.Format(TEXT("%lu"), pExtServerInfo->ServerTotalInUse);
  300. } else {
  301. NumString.LoadString(IDS_NOT_APPLICABLE);
  302. }
  303. m_ServerList.SetItemText(item, SERVERS_COL_NUMWINSTATIONS, NumString);
  304. m_ServerList.SetItemData(item, (DWORD_PTR)pServer);
  305. m_ServerList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  306. UnlockListControl();
  307. return TRUE;
  308. } // end CDomainServersPage::AddServerToList
  309. /////////////////////////////////////
  310. // F'N: CDomainServersPage::DisplayServers
  311. //
  312. void CDomainServersPage::DisplayServers()
  313. {
  314. LockListControl();
  315. // Clear out the list control
  316. m_ServerList.DeleteAllItems();
  317. // Get a pointer to our document
  318. CWinAdminDoc *doc = (CWinAdminDoc*)GetDocument();
  319. // Get a pointer to the list of servers
  320. doc->LockServerList();
  321. CObList *pServerList = doc->GetServerList();
  322. // Iterate through the Server list
  323. POSITION pos = pServerList->GetHeadPosition();
  324. while(pos) {
  325. CServer *pServer = (CServer*)pServerList->GetNext(pos);
  326. AddServerToList(pServer);
  327. } // end while(pos)
  328. doc->UnlockServerList();
  329. UnlockListControl();
  330. } // end CDomainServersPage::DisplayServers
  331. //////////////////////////////
  332. // F'N: CDomainServersPage::OnServerItemChanged
  333. //
  334. void CDomainServersPage::OnServerItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  335. {
  336. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  337. // TODO: Add your control notification handler code here
  338. CServer *pServer = (CServer*)m_ServerList.GetItemData(pLV->iItem);
  339. if(pLV->uNewState & LVIS_SELECTED) {
  340. pServer->SetSelected();
  341. }
  342. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  343. pServer->ClearSelected();
  344. }
  345. *pResult = 0;
  346. } // end CDomainServersPage::OnServerItemChanged
  347. //////////////////////////////
  348. // F'N: CDomainServersPage::OnColumnclick
  349. //
  350. void CDomainServersPage::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
  351. {
  352. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  353. // TODO: Add your control notification handler code here
  354. // If the sort column hasn't changed, flip the ascending mode.
  355. if(m_CurrentSortColumn == pNMListView->iSubItem)
  356. m_bSortAscending = !m_bSortAscending;
  357. else // New sort column, start in ascending mode
  358. m_bSortAscending = TRUE;
  359. m_CurrentSortColumn = pNMListView->iSubItem;
  360. LockListControl();
  361. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_SERVERS, &m_ServerList, m_CurrentSortColumn, m_bSortAscending);
  362. UnlockListControl();
  363. *pResult = 0;
  364. } // end CDomainServersPage::OnColumnclick
  365. //////////////////////////////
  366. // F'N: CDomainServersPage::OnContextMenu
  367. //
  368. void CDomainServersPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  369. {
  370. // TODO: Add your message handler code here
  371. UINT flags;
  372. UINT Item;
  373. CPoint ptClient = ptScreen;
  374. ScreenToClient(&ptClient);
  375. // If we got here from the keyboard,
  376. if(ptScreen.x == -1 && ptScreen.y == -1) {
  377. UINT iCount = m_ServerList.GetItemCount( );
  378. RECT rc;
  379. for( Item = 0 ; Item < iCount ; Item++ )
  380. {
  381. if( m_ServerList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  382. {
  383. m_ServerList.GetItemRect( Item , &rc , LVIR_ICON );
  384. ptScreen.x = rc.left;
  385. ptScreen.y = rc.bottom + 5;
  386. ClientToScreen( &ptScreen );
  387. break;
  388. }
  389. }
  390. if(ptScreen.x == -1 && ptScreen.y == -1)
  391. {
  392. return;
  393. }
  394. /*
  395. RECT rect;
  396. m_ServerList.GetClientRect(&rect);
  397. ptScreen.x = (rect.right - rect.left) / 2;
  398. ptScreen.y = (rect.bottom - rect.top) / 2;
  399. ClientToScreen(&ptScreen);
  400. */
  401. }
  402. else {
  403. Item = m_ServerList.HitTest(ptClient, &flags);
  404. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  405. return;
  406. }
  407. CMenu menu;
  408. menu.LoadMenu(IDR_SERVER_POPUP);
  409. // set the temp selected item so that handler doesn't think
  410. // this came from the tree
  411. // Get a pointer to our document
  412. CWinAdminDoc *doc = (CWinAdminDoc*)GetDocument();
  413. doc->SetTreeTemp(NULL, NODE_NONE);
  414. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  415. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  416. menu.DestroyMenu();
  417. } // end CDomainServersPage::OnContextMenu
  418. ////////////////////////////////
  419. // MESSAGE MAP: CDomainUsersPage
  420. //
  421. IMPLEMENT_DYNCREATE(CDomainUsersPage, CFormView)
  422. BEGIN_MESSAGE_MAP(CDomainUsersPage, CFormView)
  423. //{{AFX_MSG_MAP(CDomainUsersPage)
  424. ON_WM_SIZE()
  425. ON_NOTIFY(LVN_COLUMNCLICK, IDC_USER_LIST, OnColumnclick)
  426. ON_NOTIFY(LVN_ITEMCHANGED, IDC_USER_LIST, OnUserItemChanged)
  427. ON_WM_CONTEXTMENU()
  428. ON_NOTIFY(NM_SETFOCUS, IDC_USER_LIST, OnSetfocusUserList)
  429. //ON_NOTIFY(NM_KILLFOCUS, IDC_USER_LIST, OnKillfocusUserList)
  430. //}}AFX_MSG_MAP
  431. END_MESSAGE_MAP()
  432. /////////////////////////////
  433. // F'N: CDomainUsersPage ctor
  434. //
  435. CDomainUsersPage::CDomainUsersPage()
  436. : CAdminPage(CDomainUsersPage::IDD)
  437. {
  438. //{{AFX_DATA_INIT(CDomainUsersPage)
  439. // NOTE: the ClassWizard will add member initialization here
  440. //}}AFX_DATA_INIT
  441. m_pDomain = NULL;
  442. m_bSortAscending = TRUE;
  443. } // end CDomainUsersPage ctor
  444. /////////////////////////////
  445. // F'N: CDomainUsersPage dtor
  446. //
  447. CDomainUsersPage::~CDomainUsersPage()
  448. {
  449. } // end CDomainUsersPage dtor
  450. ////////////////////////////////////////
  451. // F'N: CDomainUsersPage::DoDataExchange
  452. //
  453. void CDomainUsersPage::DoDataExchange(CDataExchange* pDX)
  454. {
  455. CFormView::DoDataExchange(pDX);
  456. //{{AFX_DATA_MAP(CDomainUsersPage)
  457. DDX_Control(pDX, IDC_USER_LIST, m_UserList);
  458. //}}AFX_DATA_MAP
  459. } // end CDomainUsersPage::DoDataExchange
  460. #ifdef _DEBUG
  461. /////////////////////////////////////
  462. // F'N: CDomainUsersPage::AssertValid
  463. //
  464. void CDomainUsersPage::AssertValid() const
  465. {
  466. CFormView::AssertValid();
  467. } // end CDomainUsersPage::AssertValid
  468. //////////////////////////////
  469. // F'N: CDomainUsersPage::Dump
  470. //
  471. void CDomainUsersPage::Dump(CDumpContext& dc) const
  472. {
  473. CFormView::Dump(dc);
  474. } // end CDomainUsersPage::Dump
  475. #endif //_DEBUG
  476. //////////////////////////////
  477. // F'N: CDomainUsersPage::OnSize
  478. //
  479. void CDomainUsersPage::OnSize(UINT nType, int cx, int cy)
  480. {
  481. RECT rect;
  482. GetClientRect(&rect);
  483. rect.top += LIST_TOP_OFFSET;
  484. if(m_UserList.GetSafeHwnd())
  485. m_UserList.MoveWindow(&rect, TRUE);
  486. // CFormView::OnSize(nType, cx, cy);
  487. } // end CDomainUsersPage::OnSize
  488. static ColumnDef UserColumns[] = {
  489. CD_SERVER,
  490. CD_USER3,
  491. CD_SESSION,
  492. CD_ID,
  493. CD_STATE,
  494. CD_IDLETIME,
  495. CD_LOGONTIME,
  496. };
  497. #define NUM_DOMAIN_USER_COLUMNS sizeof(UserColumns)/sizeof(ColumnDef)
  498. //////////////////////////////
  499. // F'N: CDomainUsersPage::OnInitialUpdate
  500. //
  501. void CDomainUsersPage::OnInitialUpdate()
  502. {
  503. CFormView::OnInitialUpdate();
  504. BuildImageList(); // builds the image list for the list control
  505. CString columnString;
  506. for(int col = 0; col < NUM_DOMAIN_USER_COLUMNS; col++) {
  507. columnString.LoadString(UserColumns[col].stringID);
  508. m_UserList.InsertColumn(col, columnString, UserColumns[col].format, UserColumns[col].width, col);
  509. }
  510. m_CurrentSortColumn = AS_USERS_COL_SERVER;
  511. } // end CDomainUsersPage::OnInitialUpdate
  512. //////////////////////////////
  513. // F'N: CDomainUsersPage::OnUserItemChanged
  514. //
  515. void CDomainUsersPage::OnUserItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  516. {
  517. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  518. if(pLV->uNewState & LVIS_SELECTED) {
  519. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(pLV->iItem);
  520. pWinStation->SetSelected();
  521. }
  522. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  523. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(pLV->iItem);
  524. pWinStation->ClearSelected();
  525. }
  526. *pResult = 0;
  527. } // end CDomainUsersPage::OnUserItemChanged
  528. /////////////////////////////////////
  529. // F'N: CDomainUsersPage::BuildImageList
  530. //
  531. // - calls m_ImageList.Create(..) to create the image list
  532. // - calls AddIconToImageList(..) to add the icons themselves and save
  533. // off their indices
  534. // - attaches the image list to the list ctrl
  535. //
  536. void CDomainUsersPage::BuildImageList()
  537. {
  538. m_ImageList.Create(16, 16, TRUE, 2, 0);
  539. m_idxUser = AddIconToImageList(IDI_USER);
  540. m_idxCurrentUser = AddIconToImageList(IDI_CURRENT_USER);
  541. m_UserList.SetImageList(&m_ImageList, LVSIL_SMALL);
  542. } // end CDomainUsersPage::BuildImageList
  543. /////////////////////////////////////////
  544. // F'N: CDomainUsersPage::AddIconToImageList
  545. //
  546. // - loads the appropriate icon, adds it to m_ImageList, and returns
  547. // the newly-added icon's index in the image list
  548. //
  549. int CDomainUsersPage::AddIconToImageList(int iconID)
  550. {
  551. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  552. return m_ImageList.Add(hIcon);
  553. } // end CDomainUsersPage::AddIconToImageList
  554. //////////////////////////////
  555. // F'N: CDomainUsersPage::Reset
  556. //
  557. void CDomainUsersPage::Reset(void *pDomain)
  558. {
  559. ASSERT(pDomain);
  560. m_pDomain = (CDomain*)pDomain;
  561. DisplayUsers();
  562. } // end CDomainUsersPage::Reset
  563. //////////////////////////////
  564. // F'N: CDomainUsersPage::AddServer
  565. //
  566. void CDomainUsersPage::AddServer(CServer *pServer)
  567. {
  568. ASSERT(pServer);
  569. // Add the server's users to the list
  570. if(AddServerToList(pServer)) {
  571. // Sort the list
  572. LockListControl();
  573. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_USERS, &m_UserList, m_CurrentSortColumn, m_bSortAscending);
  574. UnlockListControl();
  575. }
  576. } // end CDomainUsersPage::AddServer
  577. //////////////////////////////
  578. // F'N: CDomainUsersPage::RemoveServer
  579. //
  580. void CDomainUsersPage::RemoveServer(CServer *pServer)
  581. {
  582. ASSERT(pServer);
  583. // If the server isn't in the current domain, there's nothing to do
  584. if(m_pDomain != pServer->GetDomain()) return;
  585. LockListControl();
  586. int ItemCount = m_UserList.GetItemCount();
  587. // We need to go through the list backward so that we can remove
  588. // more than one item without the item numbers getting messed up
  589. for(int item = ItemCount; item; item--) {
  590. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(item-1);
  591. CServer *pListServer = pWinStation->GetServer();
  592. if(pListServer == pServer) {
  593. m_UserList.DeleteItem(item-1);
  594. pServer->ClearAllSelected();
  595. }
  596. }
  597. UnlockListControl();
  598. } // end CDomainUsersPage::RemoveServer
  599. //////////////////////////////
  600. // F'N: CDomainUsersPage::UpdateServer
  601. //
  602. void CDomainUsersPage::UpdateServer(CServer *pServer)
  603. {
  604. ASSERT(pServer);
  605. // If the server isn't in the current domain, there's nothing to do
  606. if(m_pDomain != pServer->GetDomain()) return;
  607. if(pServer->IsState(SS_DISCONNECTING))
  608. RemoveServer(pServer);
  609. } // end CDomainUsersPage::UpdateServer
  610. //////////////////////////////
  611. // F'N: CDomainUsersPage::UpdateWinStations
  612. //
  613. void CDomainUsersPage::UpdateWinStations(CServer *pServer)
  614. {
  615. ASSERT(pServer);
  616. // If the server isn't in the current domain, there's nothing to do
  617. if(m_pDomain != pServer->GetDomain()) return;
  618. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  619. BOOL bAnyChanged = FALSE;
  620. BOOL bAnyAdded = FALSE;
  621. // Loop through the WinStations
  622. pServer->LockWinStationList();
  623. CObList *pWinStationList = pServer->GetWinStationList();
  624. POSITION pos = pWinStationList->GetHeadPosition();
  625. while(pos) {
  626. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  627. LV_FINDINFO FindInfo;
  628. FindInfo.flags = LVFI_PARAM;
  629. FindInfo.lParam = (LPARAM)pWinStation;
  630. // Find the WinStation in our list
  631. int item = m_UserList.FindItem(&FindInfo, -1);
  632. // If the WinStation is new and isn't currently in the list,
  633. // add it to the list
  634. if(pWinStation->IsNew() && pWinStation->HasUser() && item == -1) {
  635. AddUserToList(pWinStation);
  636. bAnyAdded = TRUE;
  637. continue;
  638. }
  639. // If the WinStation is no longer current,
  640. // remove it from the list
  641. if((!pWinStation->IsCurrent() || !pWinStation->HasUser()) && item != -1) {
  642. // Remove the WinStation from the list
  643. m_UserList.DeleteItem(item);
  644. pWinStation->ClearSelected();
  645. continue;
  646. }
  647. // If the WinStation info has changed, change
  648. // it's info in our tree
  649. if(pWinStation->IsChanged() && item != -1) {
  650. // change the user name
  651. m_UserList.SetItemText(item, AS_USERS_COL_USER, pWinStation->GetUserName());
  652. // change the WinStation Name
  653. // WinStation Name
  654. if(pWinStation->GetName()[0])
  655. m_UserList.SetItemText(item, AS_USERS_COL_WINSTATION, pWinStation->GetName());
  656. else {
  657. CString NameString(" ");
  658. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  659. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  660. m_UserList.SetItemText(item, AS_USERS_COL_WINSTATION, NameString);
  661. }
  662. // change the Connect State
  663. m_UserList.SetItemText(item, AS_USERS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  664. // change the Idle Time
  665. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  666. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  667. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  668. {
  669. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  670. }
  671. else wcscpy(IdleTimeString, TEXT("."));
  672. m_UserList.SetItemText(item, AS_USERS_COL_IDLETIME, IdleTimeString);
  673. // change the Logon Time
  674. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  675. // We don't want to pass a 0 logon time to DateTimeString()
  676. // It will blow up if the timezone is GMT
  677. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  678. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  679. pDoc->FixUnknownString(LogonTimeString);
  680. }
  681. else LogonTimeString[0] = '\0';
  682. // change the
  683. m_UserList.SetItemText(item, AS_USERS_COL_LOGONTIME, LogonTimeString);
  684. if(m_CurrentSortColumn != AS_USERS_COL_ID)
  685. bAnyChanged = TRUE;
  686. continue;
  687. }
  688. // If the WinStation is not in the list but now has a user, add it to the list
  689. if(item == -1 && pWinStation->IsCurrent() && pWinStation->HasUser()) {
  690. AddUserToList(pWinStation);
  691. bAnyAdded = TRUE;
  692. }
  693. }
  694. pServer->UnlockWinStationList();
  695. if(bAnyChanged || bAnyAdded) SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_USERS, &m_UserList, m_CurrentSortColumn, m_bSortAscending);
  696. } // end CDomainUsersPage::UpdateWinStations
  697. //////////////////////////////
  698. // F'N: CDomainUsersPage::AddUserToList
  699. //
  700. int CDomainUsersPage::AddUserToList(CWinStation *pWinStation)
  701. {
  702. ASSERT(pWinStation);
  703. CServer *pServer = pWinStation->GetServer();
  704. // If the server isn't in the current domain, there's nothing to do
  705. if(m_pDomain != pServer->GetDomain()) return -1;
  706. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  707. LockListControl();
  708. //////////////////////
  709. // Fill in the columns
  710. //////////////////////
  711. // Server - put at the end of the list
  712. int item = m_UserList.InsertItem(m_UserList.GetItemCount(), pServer->GetName(),
  713. pWinStation->IsCurrentUser() ? m_idxCurrentUser : m_idxUser);
  714. // User
  715. m_UserList.SetItemText(item, AS_USERS_COL_USER, pWinStation->GetUserName());
  716. // WinStation Name
  717. if(pWinStation->GetName()[0])
  718. m_UserList.SetItemText(item, AS_USERS_COL_WINSTATION, pWinStation->GetName());
  719. else {
  720. CString NameString(" ");
  721. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  722. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  723. m_UserList.SetItemText(item, AS_USERS_COL_WINSTATION, NameString);
  724. }
  725. // Logon ID
  726. CString ColumnString;
  727. ColumnString.Format(TEXT("%lu"), pWinStation->GetLogonId());
  728. m_UserList.SetItemText(item, AS_USERS_COL_ID, ColumnString);
  729. // Connect State
  730. m_UserList.SetItemText(item, AS_USERS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  731. // Idle Time
  732. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  733. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  734. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  735. {
  736. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  737. }
  738. else wcscpy(IdleTimeString, TEXT("."));
  739. m_UserList.SetItemText(item, AS_USERS_COL_IDLETIME, IdleTimeString);
  740. // Logon Time
  741. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  742. // We don't want to pass a 0 logon time to DateTimeString()
  743. // It will blow up if the timezone is GMT
  744. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  745. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  746. pDoc->FixUnknownString(LogonTimeString);
  747. }
  748. else LogonTimeString[0] = '\0';
  749. m_UserList.SetItemText(item, AS_USERS_COL_LOGONTIME, LogonTimeString);
  750. // Attach a pointer to the CWinStation structure to the list item
  751. m_UserList.SetItemData(item, (DWORD_PTR)pWinStation);
  752. //bug #191727
  753. //m_UserList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  754. UnlockListControl();
  755. return item;
  756. } // end CDomainUsersPage::AddUserToList
  757. //////////////////////////////
  758. // F'N: CDomainUsersPage::AddServerToList
  759. //
  760. BOOL CDomainUsersPage::AddServerToList(CServer *pServer)
  761. {
  762. ASSERT(pServer);
  763. // If the server isn't in the current domain, there's nothing to do
  764. if(m_pDomain != pServer->GetDomain()) return FALSE;
  765. pServer->LockWinStationList();
  766. // Get a pointer to this server's list of WinStations
  767. CObList *pWinStationList = pServer->GetWinStationList();
  768. // Iterate through the WinStation list
  769. POSITION pos = pWinStationList->GetHeadPosition();
  770. while(pos) {
  771. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  772. // only show the WinStation if it has a user
  773. if(pWinStation->HasUser()) {
  774. AddUserToList(pWinStation);
  775. }
  776. } // end while(pos)
  777. pServer->UnlockWinStationList();
  778. return TRUE;
  779. } // end CDomainUsersPage::AddServerToList
  780. //////////////////////////////
  781. // F'N: CDomainUsersPage::OnColumnclick
  782. //
  783. void CDomainUsersPage::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
  784. {
  785. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  786. // TODO: Add your control notification handler code here
  787. // If the sort column hasn't changed, flip the ascending mode.
  788. if(m_CurrentSortColumn == pNMListView->iSubItem)
  789. m_bSortAscending = !m_bSortAscending;
  790. else // New sort column, start in ascending mode
  791. m_bSortAscending = TRUE;
  792. m_CurrentSortColumn = pNMListView->iSubItem;
  793. LockListControl();
  794. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_USERS, &m_UserList, m_CurrentSortColumn, m_bSortAscending);
  795. UnlockListControl();
  796. *pResult = 0;
  797. } // end CDomainUsersPage::OnColumnclick
  798. //////////////////////////////
  799. // F'N: CDomainUsersPage::OnContextMenu
  800. //
  801. void CDomainUsersPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  802. {
  803. // TODO: Add your message handler code here
  804. UINT flags;
  805. UINT Item;
  806. CPoint ptClient = ptScreen;
  807. ScreenToClient(&ptClient);
  808. // If we got here from the keyboard,
  809. if(ptScreen.x == -1 && ptScreen.y == -1) {
  810. UINT iCount = m_UserList.GetItemCount( );
  811. RECT rc;
  812. for( Item = 0 ; Item < iCount ; Item++ )
  813. {
  814. if( m_UserList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  815. {
  816. m_UserList.GetItemRect( Item , &rc , LVIR_ICON );
  817. ptScreen.x = rc.left;
  818. ptScreen.y = rc.bottom + 5;
  819. ClientToScreen( &ptScreen );
  820. break;
  821. }
  822. }
  823. if(ptScreen.x == -1 && ptScreen.y == -1)
  824. {
  825. return;
  826. }
  827. /*
  828. RECT rect;
  829. m_UserList.GetClientRect(&rect);
  830. ptScreen.x = (rect.right - rect.left) / 2;
  831. ptScreen.y = (rect.bottom - rect.top) / 2;
  832. ClientToScreen(&ptScreen);
  833. */
  834. }
  835. else {
  836. Item = m_UserList.HitTest(ptClient, &flags);
  837. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  838. {
  839. //
  840. // ListView HitTest bug? return -1 but item display as selected.
  841. // workaround for now, Al can fix this later
  842. //
  843. UINT iCount = m_UserList.GetItemCount( );
  844. RECT rc;
  845. for( Item = 0 ; Item < iCount ; Item++ )
  846. {
  847. if( m_UserList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  848. {
  849. break;
  850. }
  851. }
  852. if( Item >= iCount )
  853. {
  854. return;
  855. }
  856. }
  857. //
  858. // NM_RCLICK (WM_NOTIFY) then WM_CNTEXTMENU but no NM_ITEMCHANGED message
  859. // manually set it to selected state
  860. //
  861. CWinStation *pWinStation = (CWinStation*)m_UserList.GetItemData(Item);
  862. if( !pWinStation )
  863. return;
  864. if( m_UserList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  865. {
  866. pWinStation->SetSelected();
  867. }
  868. }
  869. CMenu menu;
  870. menu.LoadMenu(IDR_USER_POPUP);
  871. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  872. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  873. menu.DestroyMenu();
  874. } // end CDomainUsersPage::OnContextMenu
  875. /////////////////////////////////////
  876. // F'N: CDomainUsersPage::DisplayUsers
  877. //
  878. void CDomainUsersPage::DisplayUsers()
  879. {
  880. LockListControl();
  881. // Clear out the list control
  882. m_UserList.DeleteAllItems();
  883. // Get a pointer to the document's list of servers
  884. CObList* pServerList = ((CWinAdminDoc*)GetDocument())->GetServerList();
  885. ((CWinAdminDoc*)GetDocument())->LockServerList();
  886. // Iterate through the server list
  887. POSITION pos2 = pServerList->GetHeadPosition();
  888. while(pos2) {
  889. CServer *pServer = (CServer*)pServerList->GetNext(pos2);
  890. AddServerToList(pServer);
  891. } // end while(pos2)
  892. ((CWinAdminDoc*)GetDocument())->UnlockServerList();
  893. UnlockListControl();
  894. } // end CDomainUsersPage::DisplayUsers
  895. /////////////////////////////////////
  896. // F'N: CDomainUsersPage::ClearSelections
  897. //
  898. void CDomainUsersPage::ClearSelections()
  899. {
  900. if(m_UserList.m_hWnd != NULL)
  901. {
  902. POSITION pos = m_UserList.GetFirstSelectedItemPosition();
  903. while (pos)
  904. {
  905. int nItem = m_UserList.GetNextSelectedItem(pos);
  906. m_UserList.SetItemState(nItem,0,LVIS_SELECTED);
  907. }
  908. }
  909. }
  910. ////////////////////////////////
  911. // MESSAGE MAP: CDomainWinStationsPage
  912. //
  913. IMPLEMENT_DYNCREATE(CDomainWinStationsPage, CFormView)
  914. BEGIN_MESSAGE_MAP(CDomainWinStationsPage, CFormView)
  915. //{{AFX_MSG_MAP(CDomainWinStationsPage)
  916. ON_WM_SIZE()
  917. ON_NOTIFY(LVN_COLUMNCLICK, IDC_WINSTATION_LIST, OnColumnclick)
  918. ON_NOTIFY(LVN_ITEMCHANGED, IDC_WINSTATION_LIST, OnWinStationItemChanged)
  919. ON_WM_CONTEXTMENU()
  920. ON_NOTIFY(NM_SETFOCUS, IDC_WINSTATION_LIST, OnSetfocusWinstationList)
  921. //ON_NOTIFY(NM_KILLFOCUS, IDC_WINSTATION_LIST, OnKillfocusWinstationList)
  922. //}}AFX_MSG_MAP
  923. END_MESSAGE_MAP()
  924. /////////////////////////////
  925. // F'N: CDomainWinStationsPage ctor
  926. //
  927. CDomainWinStationsPage::CDomainWinStationsPage()
  928. : CAdminPage(CDomainWinStationsPage::IDD)
  929. {
  930. //{{AFX_DATA_INIT(CDomainWinStationsPage)
  931. // NOTE: the ClassWizard will add member initialization here
  932. //}}AFX_DATA_INIT
  933. m_pDomain = NULL;
  934. m_bSortAscending = TRUE;
  935. } // end CDomainWinStationsPage ctor
  936. /////////////////////////////
  937. // F'N: CDomainWinStationsPage dtor
  938. //
  939. CDomainWinStationsPage::~CDomainWinStationsPage()
  940. {
  941. } // end CDomainWinStationsPage dtor
  942. ////////////////////////////////////////
  943. // F'N: CDomainWinStationsPage::DoDataExchange
  944. //
  945. void CDomainWinStationsPage::DoDataExchange(CDataExchange* pDX)
  946. {
  947. CFormView::DoDataExchange(pDX);
  948. //{{AFX_DATA_MAP(CDomainWinStationsPage)
  949. DDX_Control(pDX, IDC_WINSTATION_LIST, m_StationList);
  950. //}}AFX_DATA_MAP
  951. } // end CDomainWinStationsPage::DoDataExchange
  952. #ifdef _DEBUG
  953. /////////////////////////////////////
  954. // F'N: CDomainWinStationsPage::AssertValid
  955. //
  956. void CDomainWinStationsPage::AssertValid() const
  957. {
  958. CFormView::AssertValid();
  959. } // end CDomainWinStationsPage::AssertValid
  960. //////////////////////////////
  961. // F'N: CDomainWinStationsPage::Dump
  962. //
  963. void CDomainWinStationsPage::Dump(CDumpContext& dc) const
  964. {
  965. CFormView::Dump(dc);
  966. } // end CDomainWinStationsPage::Dump
  967. #endif //_DEBUG
  968. ////////////////////////////////////////
  969. // F'N: CDomainWinStationsPage::OnWinStationItemChanged
  970. //
  971. void CDomainWinStationsPage::OnWinStationItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  972. {
  973. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  974. if(pLV->uNewState & LVIS_SELECTED) {
  975. CWinStation *pWinStation = (CWinStation*)m_StationList.GetItemData(pLV->iItem);
  976. pWinStation->SetSelected();
  977. }
  978. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  979. CWinStation *pWinStation = (CWinStation*)m_StationList.GetItemData(pLV->iItem);
  980. pWinStation->ClearSelected();
  981. }
  982. *pResult = 0;
  983. } // end CDomainWinStationsPage::OnWinStationItemChanged
  984. ////////////////////////////////////////
  985. // F'N: CDomainWinStationsPage::OnSize
  986. //
  987. void CDomainWinStationsPage::OnSize(UINT nType, int cx, int cy)
  988. {
  989. RECT rect;
  990. GetClientRect(&rect);
  991. rect.top += LIST_TOP_OFFSET;
  992. if(m_StationList.GetSafeHwnd())
  993. m_StationList.MoveWindow(&rect, TRUE);
  994. // CFormView::OnSize(nType, cx, cy);
  995. } // end CDomainWinStationsPage::OnSize
  996. static ColumnDef WinsColumns[] = {
  997. CD_SERVER,
  998. CD_SESSION2,
  999. CD_USER2,
  1000. CD_ID,
  1001. CD_STATE,
  1002. CD_TYPE,
  1003. CD_CLIENT_NAME,
  1004. CD_IDLETIME,
  1005. CD_LOGONTIME,
  1006. CD_COMMENT
  1007. };
  1008. #define NUM_DOMAIN_WINS_COLUMNS sizeof(WinsColumns)/sizeof(ColumnDef)
  1009. ////////////////////////////////////////
  1010. // F'N: CDomainWinStationsPage::OnInitialUpdate
  1011. //
  1012. void CDomainWinStationsPage::OnInitialUpdate()
  1013. {
  1014. // Call the parent class
  1015. CFormView::OnInitialUpdate();
  1016. // builds the image list for the list control
  1017. BuildImageList();
  1018. // Add the column headings
  1019. CString columnString;
  1020. for(int col = 0; col < NUM_DOMAIN_WINS_COLUMNS; col++) {
  1021. columnString.LoadString(WinsColumns[col].stringID);
  1022. m_StationList.InsertColumn(col, columnString, WinsColumns[col].format, WinsColumns[col].width, col);
  1023. }
  1024. m_CurrentSortColumn = AS_WS_COL_SERVER;
  1025. } // end CDomainWinStationsPage::OnInitialUpdate
  1026. /////////////////////////////////////
  1027. // F'N: CDomainWinStationsPage::BuildImageList
  1028. //
  1029. // - calls m_ImageList.Create(..) to create the image list
  1030. // - calls AddIconToImageList(..) to add the icons themselves and save
  1031. // off their indices
  1032. // - attaches the image list to the list ctrl
  1033. //
  1034. void CDomainWinStationsPage::BuildImageList()
  1035. {
  1036. m_ImageList.Create(16, 16, TRUE, 11, 0);
  1037. m_idxBlank = AddIconToImageList(IDI_BLANK);
  1038. m_idxCitrix = AddIconToImageList(IDR_MAINFRAME);
  1039. m_idxServer = AddIconToImageList(IDI_SERVER);
  1040. m_idxConsole = AddIconToImageList(IDI_CONSOLE);
  1041. m_idxNet = AddIconToImageList(IDI_NET);
  1042. m_idxAsync = AddIconToImageList(IDI_ASYNC);
  1043. m_idxCurrentConsole = AddIconToImageList(IDI_CURRENT_CONSOLE);
  1044. m_idxCurrentNet = AddIconToImageList(IDI_CURRENT_NET);
  1045. m_idxCurrentAsync = AddIconToImageList(IDI_CURRENT_ASYNC);
  1046. m_idxDirectAsync = AddIconToImageList(IDI_DIRECT_ASYNC);
  1047. m_idxCurrentDirectAsync = AddIconToImageList(IDI_CURRENT_DIRECT_ASYNC);
  1048. m_StationList.SetImageList(&m_ImageList, LVSIL_SMALL);
  1049. } // end CDomainWinStationsPage::BuildImageList
  1050. /////////////////////////////////////////
  1051. // F'N: CDomainWinStationsPage::AddIconToImageList
  1052. //
  1053. // - loads the appropriate icon, adds it to m_ImageList, and returns
  1054. // the newly-added icon's index in the image list
  1055. //
  1056. int CDomainWinStationsPage::AddIconToImageList(int iconID)
  1057. {
  1058. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  1059. return m_ImageList.Add(hIcon);
  1060. } // end CDomainWinStationsPage::AddIconToImageList
  1061. ////////////////////////////////////////
  1062. // F'N: CDomainWinStationsPage::Reset
  1063. //
  1064. void CDomainWinStationsPage::Reset(void *pDomain)
  1065. {
  1066. ASSERT(pDomain);
  1067. m_pDomain = (CDomain*)pDomain;
  1068. DisplayStations();
  1069. } // end CDomainWinStationsPage::Reset
  1070. ////////////////////////////////////////
  1071. // F'N: CDomainWinStationsPage::AddServer
  1072. //
  1073. void CDomainWinStationsPage::AddServer(CServer *pServer)
  1074. {
  1075. ASSERT(pServer);
  1076. // Add server's WinStations to the list
  1077. if(AddServerToList(pServer)) {
  1078. // Sort the list
  1079. LockListControl();
  1080. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_WINSTATIONS, &m_StationList, m_CurrentSortColumn, m_bSortAscending);
  1081. UnlockListControl();
  1082. }
  1083. } // end CDomainWinStationsPage::AddServer
  1084. ////////////////////////////////////////
  1085. // F'N: CDomainWinStationsPage::RemoveServer
  1086. //
  1087. void CDomainWinStationsPage::RemoveServer(CServer *pServer)
  1088. {
  1089. ASSERT(pServer);
  1090. // If the server isn't in the current domain, there's nothing to do
  1091. if(m_pDomain != pServer->GetDomain()) return;
  1092. LockListControl();
  1093. int ItemCount = m_StationList.GetItemCount();
  1094. // We need to go through the list backward so that we can remove
  1095. // more than one item without the item numbers getting messed up
  1096. for(int item = ItemCount; item; item--) {
  1097. CWinStation *pWinStation = (CWinStation*)m_StationList.GetItemData(item-1);
  1098. CServer *pListServer = pWinStation->GetServer();
  1099. if(pListServer == pServer) {
  1100. m_StationList.DeleteItem(item-1);
  1101. pServer->ClearAllSelected();
  1102. }
  1103. }
  1104. UnlockListControl();
  1105. } // end CDomainWinStationsPage::RemoveServer
  1106. //////////////////////////////
  1107. // F'N: CDomainWinStationsPage::UpdateServer
  1108. //
  1109. void CDomainWinStationsPage::UpdateServer(CServer *pServer)
  1110. {
  1111. ASSERT(pServer);
  1112. // If the server isn't in the current domain, there's nothing to do
  1113. if(m_pDomain != pServer->GetDomain()) return;
  1114. if(pServer->IsState(SS_DISCONNECTING))
  1115. RemoveServer(pServer);
  1116. } // end CDomainWinStationsPage::UpdateServer
  1117. ////////////////////////////////////////
  1118. // F'N: CDomainWinStationsPage::UpdateWinStations
  1119. //
  1120. void CDomainWinStationsPage::UpdateWinStations(CServer *pServer)
  1121. {
  1122. ASSERT(pServer);
  1123. // If the server isn't in the current domain, there's nothing to do
  1124. if(m_pDomain != pServer->GetDomain()) return;
  1125. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  1126. BOOL bAnyChanged = FALSE;
  1127. BOOL bAnyAdded = FALSE;
  1128. // Loop through the WinStations
  1129. pServer->LockWinStationList();
  1130. CObList *pWinStationList = pServer->GetWinStationList();
  1131. POSITION pos = pWinStationList->GetHeadPosition();
  1132. while(pos) {
  1133. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  1134. LV_FINDINFO FindInfo;
  1135. FindInfo.flags = LVFI_PARAM;
  1136. FindInfo.lParam = (LPARAM)pWinStation;
  1137. // Find the WinStation in our list
  1138. int item = m_StationList.FindItem(&FindInfo, -1);
  1139. // If the process is new and isn't currently in the list,
  1140. // add it to the list
  1141. if(pWinStation->IsNew() && item == -1) {
  1142. AddWinStationToList(pWinStation);
  1143. bAnyAdded = TRUE;
  1144. continue;
  1145. }
  1146. // If the WinStation is no longer current,
  1147. // remove it from the list
  1148. if(!pWinStation->IsCurrent() && item != -1) {
  1149. // Remove the WinStation from the list
  1150. m_StationList.DeleteItem(item);
  1151. pWinStation->ClearSelected();
  1152. continue;
  1153. }
  1154. // If the WinStation info has changed, change
  1155. // it's info in our tree
  1156. if(pWinStation->IsChanged() && item != -1) {
  1157. // Figure out which icon to use
  1158. int WhichIcon = m_idxBlank;
  1159. BOOL CurrentWinStation = pWinStation->IsCurrentWinStation();
  1160. if(pWinStation->GetState() != State_Disconnected
  1161. && pWinStation->GetState() != State_Idle) {
  1162. switch(pWinStation->GetSdClass()) {
  1163. case SdAsync:
  1164. if(pWinStation->IsDirectAsync())
  1165. WhichIcon = CurrentWinStation ? m_idxCurrentDirectAsync : m_idxDirectAsync;
  1166. else
  1167. WhichIcon = CurrentWinStation ? m_idxCurrentAsync : m_idxAsync;
  1168. break;
  1169. case SdNetwork:
  1170. WhichIcon = CurrentWinStation ? m_idxCurrentNet : m_idxNet;
  1171. break;
  1172. default:
  1173. WhichIcon = CurrentWinStation ? m_idxCurrentConsole : m_idxConsole;
  1174. break;
  1175. }
  1176. }
  1177. m_StationList.SetItem(item, 0, LVIF_IMAGE, 0, WhichIcon, 0, 0, 0L);
  1178. // WinStation Name
  1179. if(pWinStation->GetName()[0])
  1180. m_StationList.SetItemText(item, AS_WS_COL_WINSTATION, pWinStation->GetName());
  1181. else {
  1182. CString NameString(" ");
  1183. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  1184. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  1185. m_StationList.SetItemText(item, AS_WS_COL_WINSTATION, NameString);
  1186. }
  1187. // User
  1188. m_StationList.SetItemText(item, AS_WS_COL_USER, pWinStation->GetUserName());
  1189. // Logon ID
  1190. CString ColumnString;
  1191. ColumnString.Format(TEXT("%lu"), pWinStation->GetLogonId());
  1192. m_StationList.SetItemText(item, AS_WS_COL_ID, ColumnString);
  1193. // Connect State
  1194. m_StationList.SetItemText(item, AS_WS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  1195. // Type
  1196. m_StationList.SetItemText(item, AS_WS_COL_TYPE, pWinStation->GetWdName());
  1197. // Client Name
  1198. m_StationList.SetItemText(item, AS_WS_COL_CLIENTNAME, pWinStation->GetClientName());
  1199. // Idle Time
  1200. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  1201. ELAPSEDTIME IdleTime = pWinStation->GetIdleTime();
  1202. if(IdleTime.days || IdleTime.hours || IdleTime.minutes || IdleTime.seconds)
  1203. {
  1204. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  1205. }
  1206. else wcscpy(IdleTimeString, TEXT("."));
  1207. m_StationList.SetItemText(item, AS_WS_COL_IDLETIME, IdleTimeString);
  1208. // Logon Time
  1209. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  1210. // We don't want to pass a 0 logon time to DateTimeString()
  1211. // It will blow up if the timezone is GMT
  1212. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  1213. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  1214. pDoc->FixUnknownString(LogonTimeString);
  1215. }
  1216. else LogonTimeString[0] = '\0';
  1217. m_StationList.SetItemText(item, AS_WS_COL_LOGONTIME, LogonTimeString);
  1218. // Comment
  1219. m_StationList.SetItemText(item, AS_WS_COL_COMMENT, pWinStation->GetComment());
  1220. if(m_CurrentSortColumn != AS_WS_COL_ID)
  1221. bAnyChanged = TRUE;
  1222. }
  1223. }
  1224. pServer->UnlockWinStationList();
  1225. if(bAnyChanged || bAnyAdded) SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_WINSTATIONS, &m_StationList, m_CurrentSortColumn, m_bSortAscending);
  1226. } // end CDomainWinStationsPage::UpdateWinStations
  1227. ////////////////////////////////////////
  1228. // F'N: CDomainWinStationsPage::AddWinStationToList
  1229. //
  1230. int CDomainWinStationsPage::AddWinStationToList(CWinStation *pWinStation)
  1231. {
  1232. ASSERT(pWinStation);
  1233. CServer *pServer = pWinStation->GetServer();
  1234. // If the server isn't in the current domain, there's nothing to do
  1235. if(m_pDomain != pServer->GetDomain()) return -1;
  1236. CWinAdminDoc *pDoc = (CWinAdminDoc*)((CWinAdminApp*)AfxGetApp())->GetDocument();
  1237. // Figure out which icon to use
  1238. int WhichIcon = m_idxBlank;
  1239. BOOL bCurrentWinStation = pWinStation->IsCurrentWinStation();
  1240. if(pWinStation->GetState() != State_Disconnected
  1241. && pWinStation->GetState() != State_Idle) {
  1242. switch(pWinStation->GetSdClass()) {
  1243. case SdAsync:
  1244. if(pWinStation->IsDirectAsync())
  1245. WhichIcon = bCurrentWinStation ? m_idxCurrentDirectAsync : m_idxDirectAsync;
  1246. else
  1247. WhichIcon = bCurrentWinStation ? m_idxCurrentAsync : m_idxAsync;
  1248. break;
  1249. case SdNetwork:
  1250. WhichIcon = bCurrentWinStation ? m_idxCurrentNet : m_idxNet;
  1251. break;
  1252. default:
  1253. WhichIcon = bCurrentWinStation ? m_idxCurrentConsole : m_idxConsole;
  1254. break;
  1255. }
  1256. }
  1257. LockListControl();
  1258. //////////////////////
  1259. // Fill in the columns
  1260. //////////////////////
  1261. // Server Name
  1262. int item = m_StationList.InsertItem(m_StationList.GetItemCount(), pServer->GetName(), WhichIcon);
  1263. // WinStation Name
  1264. if(pWinStation->GetName()[0])
  1265. m_StationList.SetItemText(item, AS_WS_COL_WINSTATION, pWinStation->GetName());
  1266. else {
  1267. CString NameString(" ");
  1268. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  1269. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  1270. m_StationList.SetItemText(item, AS_WS_COL_WINSTATION, NameString);
  1271. }
  1272. // User
  1273. m_StationList.SetItemText(item, AS_WS_COL_USER, pWinStation->GetUserName());
  1274. // Logon ID
  1275. CString ColumnString;
  1276. ColumnString.Format(TEXT("%lu"), pWinStation->GetLogonId());
  1277. m_StationList.SetItemText(item, AS_WS_COL_ID, ColumnString);
  1278. // Connect State
  1279. m_StationList.SetItemText(item, AS_WS_COL_STATE, StrConnectState(pWinStation->GetState(), FALSE));
  1280. // Type
  1281. m_StationList.SetItemText(item, AS_WS_COL_TYPE, pWinStation->GetWdName());
  1282. // Client Name
  1283. m_StationList.SetItemText(item, AS_WS_COL_CLIENTNAME, pWinStation->GetClientName());
  1284. // Idle Time
  1285. TCHAR IdleTimeString[MAX_ELAPSED_TIME_LENGTH];
  1286. if(pWinStation->GetState() == State_Active
  1287. && pWinStation->GetLastInputTime().QuadPart <= pWinStation->GetCurrentTime().QuadPart)
  1288. {
  1289. LARGE_INTEGER DiffTime = CalculateDiffTime(pWinStation->GetLastInputTime(), pWinStation->GetCurrentTime());
  1290. ULONG_PTR d_time = ( ULONG_PTR )DiffTime.QuadPart;
  1291. ELAPSEDTIME IdleTime;
  1292. // Calculate the days, hours, minutes, seconds since specified time.
  1293. IdleTime.days = (USHORT)(d_time / 86400L); // days since
  1294. d_time = d_time % 86400L; // seconds => partial day
  1295. IdleTime.hours = (USHORT)(d_time / 3600L); // hours since
  1296. d_time = d_time % 3600L; // seconds => partial hour
  1297. IdleTime.minutes = (USHORT)(d_time / 60L); // minutes since
  1298. IdleTime.seconds = (USHORT)(d_time % 60L);// seconds remaining
  1299. ElapsedTimeString( &IdleTime, FALSE, IdleTimeString);
  1300. pWinStation->SetIdleTime(IdleTime);
  1301. }
  1302. else wcscpy(IdleTimeString, TEXT("."));
  1303. m_StationList.SetItemText(item, AS_WS_COL_IDLETIME, IdleTimeString);
  1304. // Logon Time
  1305. TCHAR LogonTimeString[MAX_DATE_TIME_LENGTH];
  1306. // We don't want to pass a 0 logon time to DateTimeString()
  1307. // It will blow up if the timezone is GMT
  1308. if(pWinStation->GetState() == State_Active && pWinStation->GetLogonTime().QuadPart) {
  1309. DateTimeString(&(pWinStation->GetLogonTime()), LogonTimeString);
  1310. pDoc->FixUnknownString(LogonTimeString);
  1311. }
  1312. else LogonTimeString[0] = '\0';
  1313. m_StationList.SetItemText(item, AS_WS_COL_LOGONTIME, LogonTimeString);
  1314. // Comment
  1315. m_StationList.SetItemText(item, AS_WS_COL_COMMENT, pWinStation->GetComment());
  1316. // Attach a pointer to the CWinStation structure to the list item
  1317. m_StationList.SetItemData(item, (DWORD_PTR)pWinStation);
  1318. //bug #191727
  1319. //m_StationList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  1320. UnlockListControl();
  1321. return item;
  1322. } // end CDomainWinStationsPage::AddWinStationToList
  1323. ////////////////////////////////////////
  1324. // F'N: CDomainWinStationsPage::AddServerToList
  1325. //
  1326. BOOL CDomainWinStationsPage::AddServerToList(CServer *pServer)
  1327. {
  1328. ASSERT(pServer);
  1329. // If the server isn't in the current domain, there's nothing to do
  1330. if(m_pDomain != pServer->GetDomain()) return FALSE;
  1331. pServer->LockWinStationList();
  1332. // Get a pointer to this server's list of WinStations
  1333. CObList *pWinStationList = pServer->GetWinStationList();
  1334. // Iterate through the WinStation list
  1335. POSITION pos = pWinStationList->GetHeadPosition();
  1336. while(pos) {
  1337. CWinStation *pWinStation = (CWinStation*)pWinStationList->GetNext(pos);
  1338. AddWinStationToList(pWinStation);
  1339. }
  1340. pServer->UnlockWinStationList();
  1341. return TRUE;
  1342. } // end CDomainWinStationsPage::AddServerToList
  1343. /////////////////////////////////////
  1344. // F'N: CDomainWinStationsPage::DisplayStations
  1345. //
  1346. void CDomainWinStationsPage::DisplayStations()
  1347. {
  1348. // Clear out the list control
  1349. m_StationList.DeleteAllItems();
  1350. // Get a pointer to the document's list of servers
  1351. CObList* pServerList = ((CWinAdminDoc*)GetDocument())->GetServerList();
  1352. ((CWinAdminDoc*)GetDocument())->LockServerList();
  1353. // Iterate through the server list
  1354. POSITION pos = pServerList->GetHeadPosition();
  1355. while(pos) {
  1356. CServer *pServer = (CServer*)pServerList->GetNext(pos);
  1357. AddServerToList(pServer);
  1358. }
  1359. ((CWinAdminDoc*)GetDocument())->UnlockServerList();
  1360. } // end CDomainWinStationsPage::DisplayStations
  1361. ////////////////////////////////////////
  1362. // F'N: CDomainWinStationsPage::OnColumnclick
  1363. //
  1364. void CDomainWinStationsPage::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
  1365. {
  1366. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1367. // TODO: Add your control notification handler code here
  1368. // If the sort column hasn't changed, flip the ascending mode.
  1369. if(m_CurrentSortColumn == pNMListView->iSubItem)
  1370. m_bSortAscending = !m_bSortAscending;
  1371. else // New sort column, start in ascending mode
  1372. m_bSortAscending = TRUE;
  1373. m_CurrentSortColumn = pNMListView->iSubItem;
  1374. LockListControl();
  1375. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_WINSTATIONS, &m_StationList, m_CurrentSortColumn, m_bSortAscending);
  1376. UnlockListControl();
  1377. *pResult = 0;
  1378. } // end CDomainWinStationsPage::OnColumnclick
  1379. ////////////////////////////////////////
  1380. // F'N: CDomainWinStationsPage::OnContextMenu
  1381. //
  1382. void CDomainWinStationsPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  1383. {
  1384. // TODO: Add your message handler code here
  1385. UINT flags;
  1386. UINT Item;
  1387. CPoint ptClient = ptScreen;
  1388. ScreenToClient(&ptClient);
  1389. // If we got here from the keyboard,
  1390. if(ptScreen.x == -1 && ptScreen.y == -1) {
  1391. UINT iCount = m_StationList.GetItemCount( );
  1392. RECT rc;
  1393. for( Item = 0 ; Item < iCount ; Item++ )
  1394. {
  1395. if( m_StationList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  1396. {
  1397. m_StationList.GetItemRect( Item , &rc , LVIR_ICON );
  1398. ptScreen.x = rc.left;
  1399. ptScreen.y = rc.bottom + 5;
  1400. ClientToScreen( &ptScreen );
  1401. break;
  1402. }
  1403. }
  1404. if(ptScreen.x == -1 && ptScreen.y == -1)
  1405. {
  1406. return;
  1407. }
  1408. /*
  1409. RECT rect;
  1410. m_StationList.GetClientRect(&rect);
  1411. ptScreen.x = (rect.right - rect.left) / 2;
  1412. ptScreen.y = (rect.bottom - rect.top) / 2;
  1413. ClientToScreen(&ptScreen);
  1414. */
  1415. }
  1416. else {
  1417. Item = m_StationList.HitTest(ptClient, &flags);
  1418. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  1419. return;
  1420. }
  1421. CMenu menu;
  1422. menu.LoadMenu(IDR_WINSTATION_POPUP);
  1423. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  1424. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  1425. menu.DestroyMenu();
  1426. } // end CDomainWinStationsPage::OnContextMenu
  1427. /////////////////////////////////////
  1428. // F'N: CDomainWinStationsPage::ClearSelections
  1429. //
  1430. void CDomainWinStationsPage::ClearSelections()
  1431. {
  1432. if(m_StationList.m_hWnd != NULL)
  1433. {
  1434. POSITION pos = m_StationList.GetFirstSelectedItemPosition();
  1435. while (pos)
  1436. {
  1437. int nItem = m_StationList.GetNextSelectedItem(pos);
  1438. m_StationList.SetItemState(nItem,0,LVIS_SELECTED);
  1439. }
  1440. }
  1441. }
  1442. //////////////////////////////////
  1443. // MESSAGE MAP: CDomainProcessesPage
  1444. //
  1445. IMPLEMENT_DYNCREATE(CDomainProcessesPage, CFormView)
  1446. BEGIN_MESSAGE_MAP(CDomainProcessesPage, CFormView)
  1447. //{{AFX_MSG_MAP(CDomainProcessesPage)
  1448. ON_WM_SIZE()
  1449. ON_NOTIFY(LVN_COLUMNCLICK, IDC_PROCESS_LIST, OnColumnclick)
  1450. ON_NOTIFY(LVN_ITEMCHANGED, IDC_PROCESS_LIST, OnProcessItemChanged)
  1451. ON_WM_CONTEXTMENU()
  1452. ON_NOTIFY(NM_SETFOCUS, IDC_PROCESS_LIST, OnSetfocusProcessList)
  1453. //ON_NOTIFY(NM_KILLFOCUS, IDC_PROCESS_LIST, OnKillfocusProcessList)
  1454. //}}AFX_MSG_MAP
  1455. END_MESSAGE_MAP()
  1456. ///////////////////////////////
  1457. // F'N: CDomainProcessesPage ctor
  1458. //
  1459. CDomainProcessesPage::CDomainProcessesPage()
  1460. : CAdminPage(CDomainProcessesPage::IDD)
  1461. {
  1462. //{{AFX_DATA_INIT(CDomainProcessesPage)
  1463. // NOTE: the ClassWizard will add member initialization here
  1464. //}}AFX_DATA_INIT
  1465. m_pDomain = NULL;
  1466. m_bSortAscending = TRUE;
  1467. } // end CDomainProcessesPage ctor
  1468. ///////////////////////////////
  1469. // F'N: CDomainProcessesPage dtor
  1470. //
  1471. CDomainProcessesPage::~CDomainProcessesPage()
  1472. {
  1473. } // end CDomainProcessesPage dtor
  1474. //////////////////////////////////////////
  1475. // F'N: CDomainProcessesPage::DoDataExchange
  1476. //
  1477. void CDomainProcessesPage::DoDataExchange(CDataExchange* pDX)
  1478. {
  1479. CFormView::DoDataExchange(pDX);
  1480. //{{AFX_DATA_MAP(CDomainProcessesPage)
  1481. // NOTE: the ClassWizard will add DDX and DDV calls here
  1482. DDX_Control(pDX, IDC_PROCESS_LIST, m_ProcessList);
  1483. //}}AFX_DATA_MAP
  1484. } // end CDomainProcessesPage::DoDataExchange
  1485. #ifdef _DEBUG
  1486. ///////////////////////////////////////
  1487. // F'N: CDomainProcessesPage::AssertValid
  1488. //
  1489. void CDomainProcessesPage::AssertValid() const
  1490. {
  1491. CFormView::AssertValid();
  1492. } // end CDomainProcessesPage::AssertValid
  1493. ////////////////////////////////
  1494. // F'N: CDomainProcessesPage::Dump
  1495. //
  1496. void CDomainProcessesPage::Dump(CDumpContext& dc) const
  1497. {
  1498. CFormView::Dump(dc);
  1499. } // end CDomainProcessesPage::Dump
  1500. #endif //_DEBUG
  1501. //////////////////////////////////////////
  1502. // F'N: CDomainProcessesPage::OnSize
  1503. //
  1504. void CDomainProcessesPage::OnSize(UINT nType, int cx, int cy)
  1505. {
  1506. RECT rect;
  1507. GetClientRect(&rect);
  1508. rect.top += LIST_TOP_OFFSET;
  1509. if(m_ProcessList.GetSafeHwnd())
  1510. m_ProcessList.MoveWindow(&rect, TRUE);
  1511. // CFormView::OnSize(nType, cx, cy);
  1512. } // end CDomainProcessesPage::OnSize
  1513. static ColumnDef ProcColumns[] = {
  1514. CD_SERVER,
  1515. CD_USER,
  1516. CD_SESSION,
  1517. CD_PROC_ID,
  1518. CD_PROC_PID,
  1519. CD_PROC_IMAGE
  1520. };
  1521. #define NUM_DOMAIN_PROC_COLUMNS sizeof(ProcColumns)/sizeof(ColumnDef)
  1522. //////////////////////////////////////////
  1523. // F'N: CDomainProcessesPage::OnInitialUpdate
  1524. //
  1525. void CDomainProcessesPage::OnInitialUpdate()
  1526. {
  1527. CFormView::OnInitialUpdate();
  1528. // Add the column headings
  1529. CString columnString;
  1530. for(int col = 0; col < NUM_DOMAIN_PROC_COLUMNS; col++) {
  1531. columnString.LoadString(ProcColumns[col].stringID);
  1532. m_ProcessList.InsertColumn(col, columnString, ProcColumns[col].format, ProcColumns[col].width, col);
  1533. }
  1534. m_CurrentSortColumn = AS_PROC_COL_SERVER;
  1535. } // end CDomainProcessesPage::OnInitialUpdate
  1536. ////////////////////////////////
  1537. // F'N: CDomainProcessesPage::Reset
  1538. //
  1539. void CDomainProcessesPage::Reset(void *pDomain)
  1540. {
  1541. ASSERT(pDomain);
  1542. // We don't want to display processes until the user clicks
  1543. // on the "Processes" tab
  1544. m_pDomain = (CDomain*)pDomain;
  1545. } // end CDomainProcessesPage::Reset
  1546. //////////////////////////////////////////
  1547. // F'N: CDomainProcessesPage::AddServer
  1548. //
  1549. void CDomainProcessesPage::AddServer(CServer *pServer)
  1550. {
  1551. ASSERT(pServer);
  1552. // Add the Server's processes to the list
  1553. if(AddServerToList(pServer)) {
  1554. // Sort the list
  1555. LockListControl();
  1556. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_PROCESSES, &m_ProcessList, m_CurrentSortColumn, m_bSortAscending);
  1557. UnlockListControl();
  1558. }
  1559. } // end CDomainProcessesPage::AddServer
  1560. //////////////////////////////////////////
  1561. // F'N: CDomainProcessesPage::RemoveServer
  1562. //
  1563. void CDomainProcessesPage::RemoveServer(CServer *pServer)
  1564. {
  1565. ASSERT(pServer);
  1566. // If the server isn't in the current domain, there's nothing to do
  1567. if(m_pDomain != pServer->GetDomain()) return;
  1568. LockListControl();
  1569. int ItemCount = m_ProcessList.GetItemCount();
  1570. // We need to go through the list backward so that we can remove
  1571. // more than one item without the item numbers getting messed up
  1572. for(int item = ItemCount; item; item--) {
  1573. CProcess *pProcess = (CProcess*)m_ProcessList.GetItemData(item-1);
  1574. CServer *pListServer = pProcess->GetServer();
  1575. if(pListServer == pServer) {
  1576. m_ProcessList.DeleteItem(item-1);
  1577. pServer->ClearAllSelected();
  1578. }
  1579. }
  1580. UnlockListControl();
  1581. } // end CDomainProcessesPage::RemoveServer
  1582. //////////////////////////////
  1583. // F'N: CDomainProcessesPage::UpdateServer
  1584. //
  1585. void CDomainProcessesPage::UpdateServer(CServer *pServer)
  1586. {
  1587. ASSERT(pServer);
  1588. // If the server isn't in the current domain, there's nothing to do
  1589. if(m_pDomain != pServer->GetDomain()) return;
  1590. if(pServer->IsState(SS_DISCONNECTING))
  1591. RemoveServer(pServer);
  1592. } // end CDomainProcessesPage::UpdateServer
  1593. //////////////////////////////////////////
  1594. // F'N: CDomainProcessesPage::UpdateProcesses
  1595. //
  1596. void CDomainProcessesPage::UpdateProcesses(CServer *pServer)
  1597. {
  1598. ASSERT(pServer);
  1599. // If the server isn't in the current domain, there's nothing to do
  1600. if(m_pDomain != pServer->GetDomain()) return;
  1601. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1602. BOOL bAnyChanged = FALSE;
  1603. BOOL bAnyAdded = FALSE;
  1604. // Loop through the processes
  1605. pServer->LockProcessList();
  1606. CObList *pProcessList = pServer->GetProcessList();
  1607. POSITION pos = pProcessList->GetHeadPosition();
  1608. while(pos) {
  1609. CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos);
  1610. // If this is a 'system' process and we aren't currently showing them,
  1611. // go to the next process
  1612. if(pProcess->IsSystemProcess() && !pApp->ShowSystemProcesses())
  1613. continue;
  1614. // If this user is not an Admin, don't show him someone else's processes unless it
  1615. // is a System process
  1616. if(!pApp->IsUserAdmin() && !pProcess->IsCurrentUsers() && !pProcess->IsSystemProcess())
  1617. continue;
  1618. // If the process is new, add it to the list
  1619. if(pProcess->IsNew()) {
  1620. if(AddProcessToList(pProcess) != -1)
  1621. bAnyAdded = TRUE;
  1622. continue;
  1623. }
  1624. LV_FINDINFO FindInfo;
  1625. FindInfo.flags = LVFI_PARAM;
  1626. FindInfo.lParam = (LPARAM)pProcess;
  1627. // Find the Process in our list
  1628. int item = m_ProcessList.FindItem(&FindInfo, -1);
  1629. // If the process is no longer current,
  1630. // remove it from the list
  1631. if(!pProcess->IsCurrent() && item != -1) {
  1632. // Remove the Process from the list
  1633. m_ProcessList.DeleteItem(item);
  1634. pProcess->ClearSelected();
  1635. }
  1636. // If the process info has changed, change
  1637. // it's info in our tree
  1638. if(pProcess->IsChanged() && item != -1)
  1639. {
  1640. // WinStation Name
  1641. CWinStation *pWinStation = pProcess->GetWinStation();
  1642. if(pWinStation)
  1643. {
  1644. if(pWinStation->GetName()[0])
  1645. m_ProcessList.SetItemText(item, AS_PROC_COL_WINSTATION, pWinStation->GetName());
  1646. else
  1647. {
  1648. CString NameString(" ");
  1649. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  1650. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  1651. m_ProcessList.SetItemText(item, AS_PROC_COL_WINSTATION, NameString);
  1652. }
  1653. }
  1654. if(m_CurrentSortColumn == AS_PROC_COL_WINSTATION)
  1655. bAnyChanged = TRUE;
  1656. }
  1657. }
  1658. pServer->UnlockProcessList();
  1659. if(bAnyChanged || bAnyAdded) {
  1660. LockListControl();
  1661. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_PROCESSES, &m_ProcessList, m_CurrentSortColumn, m_bSortAscending);
  1662. UnlockListControl();
  1663. }
  1664. } // end CDomainProcessesPage::UpdateProcesses
  1665. //////////////////////////////////////////
  1666. // F'N: CDomainProcessesPage::RemoveProcess
  1667. //
  1668. void CDomainProcessesPage::RemoveProcess(CProcess *pProcess)
  1669. {
  1670. ASSERT(pProcess);
  1671. // If the server isn't in the current domain, there's nothing to do
  1672. if(m_pDomain != pProcess->GetServer()->GetDomain()) return;
  1673. LockListControl();
  1674. // Find out how many items in the list
  1675. int ItemCount = m_ProcessList.GetItemCount();
  1676. // Go through the items and remove this process
  1677. for(int item = 0; item < ItemCount; item++) {
  1678. CProcess *pListProcess = (CProcess*)m_ProcessList.GetItemData(item);
  1679. if(pListProcess == pProcess) {
  1680. m_ProcessList.DeleteItem(item);
  1681. break;
  1682. }
  1683. }
  1684. UnlockListControl();
  1685. }
  1686. //////////////////////////////////////////
  1687. // F'N: CDomainProcessesPage::AddProcessToList
  1688. //
  1689. int CDomainProcessesPage::AddProcessToList(CProcess *pProcess)
  1690. {
  1691. ASSERT(pProcess);
  1692. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1693. CServer *pServer = pProcess->GetServer();
  1694. // If the server isn't in the current domain, there's nothing to do
  1695. if(m_pDomain != pServer->GetDomain()) return -1;
  1696. LockListControl();
  1697. // Server - put at end of list
  1698. int item = m_ProcessList.InsertItem(m_ProcessList.GetItemCount(), pProcess->GetServer()->GetName(), NULL);
  1699. // User
  1700. m_ProcessList.SetItemText(item, AS_PROC_COL_USER, pProcess->GetUserName());
  1701. // WinStation Name
  1702. CWinStation *pWinStation = pProcess->GetWinStation();
  1703. if(pWinStation) {
  1704. if(pWinStation->GetName()[0])
  1705. m_ProcessList.SetItemText(item, AS_PROC_COL_WINSTATION, pWinStation->GetName());
  1706. else {
  1707. CString NameString(" ");
  1708. if(pWinStation->GetState() == State_Disconnected) NameString.LoadString(IDS_DISCONNECTED);
  1709. if(pWinStation->GetState() == State_Idle) NameString.LoadString(IDS_IDLE);
  1710. m_ProcessList.SetItemText(item, AS_PROC_COL_WINSTATION, NameString);
  1711. }
  1712. }
  1713. // ID
  1714. CString ProcString;
  1715. ProcString.Format(TEXT("%lu"), pProcess->GetLogonId());
  1716. m_ProcessList.SetItemText(item, AS_PROC_COL_ID, ProcString);
  1717. // PID
  1718. ProcString.Format(TEXT("%lu"), pProcess->GetPID());
  1719. m_ProcessList.SetItemText(item, AS_PROC_COL_PID, ProcString);
  1720. // Image
  1721. m_ProcessList.SetItemText(item, AS_PROC_COL_IMAGE, pProcess->GetImageName());
  1722. m_ProcessList.SetItemData(item, (DWORD_PTR)pProcess);
  1723. m_ProcessList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_SELECTED | LVIS_FOCUSED );
  1724. UnlockListControl();
  1725. return item;
  1726. } // end CDomainProcessesPage::AddProcessToList
  1727. ////////////////////////////////
  1728. // F'N: CDomainProcessesPage::AddServerToList
  1729. //
  1730. BOOL CDomainProcessesPage::AddServerToList(CServer *pServer)
  1731. {
  1732. ASSERT(pServer);
  1733. // If the server isn't in the current domain, there's nothing to do
  1734. if(m_pDomain != pServer->GetDomain()) return FALSE;
  1735. CWinAdminApp *pApp = (CWinAdminApp*)AfxGetApp();
  1736. pServer->EnumerateProcesses();
  1737. CObList *pProcessList = pServer->GetProcessList();
  1738. pServer->LockProcessList();
  1739. POSITION pos = pProcessList->GetHeadPosition();
  1740. while(pos) {
  1741. CProcess *pProcess = (CProcess*)pProcessList->GetNext(pos);
  1742. // If this is a 'system' process and we aren't currently showing them,
  1743. // go to the next process
  1744. if(pProcess->IsSystemProcess() && !pApp->ShowSystemProcesses())
  1745. continue;
  1746. // If this user is not an Admin, don't show him someone else's processes unless it
  1747. // is a System process
  1748. if(!pApp->IsUserAdmin() && !pProcess->IsCurrentUsers() && !pProcess->IsSystemProcess())
  1749. continue;
  1750. AddProcessToList(pProcess);
  1751. }
  1752. pServer->UnlockProcessList();
  1753. return TRUE;
  1754. } // end CDomainProcessesPage::AddServerToList
  1755. ////////////////////////////////
  1756. // F'N: CDomainProcessesPage::DisplayProcesses
  1757. //
  1758. void CDomainProcessesPage::DisplayProcesses()
  1759. {
  1760. CWaitCursor Nikki;
  1761. LockListControl();
  1762. // Clear out the list control
  1763. m_ProcessList.DeleteAllItems();
  1764. // Get a pointer to the document's list of servers
  1765. CObList* pServerList = ((CWinAdminDoc*)GetDocument())->GetServerList();
  1766. ((CWinAdminDoc*)GetDocument())->LockServerList();
  1767. // Iterate through the server list
  1768. POSITION pos = pServerList->GetHeadPosition();
  1769. while(pos) {
  1770. CServer *pServer = (CServer*)pServerList->GetNext(pos);
  1771. if(pServer->IsServerSane()) {
  1772. AddServerToList(pServer);
  1773. } // end if(pServer->IsServerSane())
  1774. } // end while(pos)
  1775. ((CWinAdminDoc*)GetDocument())->UnlockServerList();
  1776. UnlockListControl();
  1777. } // end CDomainProcessesPage::DisplayProcesses
  1778. //////////////////////////////////////////
  1779. // F'N: CDomainProcessesPage::OnProcessItemChanged
  1780. //
  1781. void CDomainProcessesPage::OnProcessItemChanged(NMHDR* pNMHDR, LRESULT* pResult)
  1782. {
  1783. NM_LISTVIEW *pLV = (NM_LISTVIEW*)pNMHDR;
  1784. if(pLV->uNewState & LVIS_SELECTED) {
  1785. CProcess *pProcess = (CProcess*)m_ProcessList.GetItemData(pLV->iItem);
  1786. pProcess->SetSelected();
  1787. }
  1788. if(pLV->uOldState & LVIS_SELECTED && !(pLV->uNewState & LVIS_SELECTED)) {
  1789. CProcess *pProcess = (CProcess*)m_ProcessList.GetItemData(pLV->iItem);
  1790. pProcess->ClearSelected();
  1791. }
  1792. *pResult = 0;
  1793. } // end CDomainProcessesPage::OnProcessItemChanged
  1794. //////////////////////////////////////////
  1795. // F'N: CDomainProcessesPage::OnColumnclick
  1796. //
  1797. void CDomainProcessesPage::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
  1798. {
  1799. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  1800. // TODO: Add your control notification handler code here
  1801. // If the sort column hasn't changed, flip the ascending mode.
  1802. if(m_CurrentSortColumn == pNMListView->iSubItem)
  1803. m_bSortAscending = !m_bSortAscending;
  1804. else // New sort column, start in ascending mode
  1805. m_bSortAscending = TRUE;
  1806. m_CurrentSortColumn = pNMListView->iSubItem;
  1807. LockListControl();
  1808. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_PROCESSES, &m_ProcessList, m_CurrentSortColumn, m_bSortAscending);
  1809. UnlockListControl();
  1810. *pResult = 0;
  1811. } // end CDomainProcessesPage::OnColumnclick
  1812. //////////////////////////////////////////
  1813. // F'N: CDomainProcessesPage::OnContextMenu
  1814. //
  1815. void CDomainProcessesPage::OnContextMenu(CWnd* pWnd, CPoint ptScreen)
  1816. {
  1817. // TODO: Add your message handler code here
  1818. UINT flags;
  1819. UINT Item;
  1820. CPoint ptClient = ptScreen;
  1821. ScreenToClient(&ptClient);
  1822. // If we got here from the keyboard,
  1823. if(ptScreen.x == -1 && ptScreen.y == -1) {
  1824. UINT iCount = m_ProcessList.GetItemCount( );
  1825. RECT rc;
  1826. for( Item = 0 ; Item < iCount ; Item++ )
  1827. {
  1828. if( m_ProcessList.GetItemState( Item , LVIS_SELECTED ) == LVIS_SELECTED )
  1829. {
  1830. m_ProcessList.GetItemRect( Item , &rc , LVIR_ICON );
  1831. ptScreen.x = rc.left;
  1832. ptScreen.y = rc.bottom + 5;
  1833. ClientToScreen( &ptScreen );
  1834. break;
  1835. }
  1836. }
  1837. if(ptScreen.x == -1 && ptScreen.y == -1)
  1838. {
  1839. return;
  1840. }
  1841. /*
  1842. RECT rect;
  1843. m_ProcessList.GetClientRect(&rect);
  1844. ptScreen.x = (rect.right - rect.left) / 2;
  1845. ptScreen.y = (rect.bottom - rect.top) / 2;
  1846. ClientToScreen(&ptScreen);
  1847. */
  1848. }
  1849. else {
  1850. Item = m_ProcessList.HitTest(ptClient, &flags);
  1851. if((Item == 0xFFFFFFFF) || !(flags & LVHT_ONITEM))
  1852. return;
  1853. }
  1854. CMenu menu;
  1855. menu.LoadMenu(IDR_PROCESS_POPUP);
  1856. menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON |
  1857. TPM_RIGHTBUTTON, ptScreen.x, ptScreen.y, AfxGetMainWnd());
  1858. menu.DestroyMenu();
  1859. } // end CDomainProcessesPage::OnContextMenu
  1860. ////////////////////////////////
  1861. // MESSAGE MAP: CDomainLicensesPage
  1862. //
  1863. IMPLEMENT_DYNCREATE(CDomainLicensesPage, CFormView)
  1864. BEGIN_MESSAGE_MAP(CDomainLicensesPage, CFormView)
  1865. //{{AFX_MSG_MAP(CDomainLicensesPage)
  1866. ON_WM_SIZE()
  1867. ON_NOTIFY(LVN_COLUMNCLICK, IDC_LICENSE_LIST, OnColumnclick)
  1868. ON_NOTIFY(NM_SETFOCUS, IDC_LICENSE_LIST, OnSetfocusLicenseList)
  1869. //ON_NOTIFY(NM_KILLFOCUS, IDC_LICENSE_LIST, OnKillfocusLicenseList)
  1870. //}}AFX_MSG_MAP
  1871. END_MESSAGE_MAP()
  1872. /////////////////////////////
  1873. // F'N: CDomainLicensesPage ctor
  1874. //
  1875. CDomainLicensesPage::CDomainLicensesPage()
  1876. : CAdminPage(CDomainLicensesPage::IDD)
  1877. {
  1878. //{{AFX_DATA_INIT(CDomainLicensesPage)
  1879. // NOTE: the ClassWizard will add member initialization here
  1880. //}}AFX_DATA_INIT
  1881. m_pDomain = NULL;
  1882. m_bSortAscending = TRUE;
  1883. } // end CDomainLicensesPage ctor
  1884. /////////////////////////////
  1885. // F'N: CDomainLicensesPage dtor
  1886. //
  1887. CDomainLicensesPage::~CDomainLicensesPage()
  1888. {
  1889. } // end CDomainLicensesPage dtor
  1890. ////////////////////////////////////////
  1891. // F'N: CDomainLicensesPage::DoDataExchange
  1892. //
  1893. void CDomainLicensesPage::DoDataExchange(CDataExchange* pDX)
  1894. {
  1895. CFormView::DoDataExchange(pDX);
  1896. //{{AFX_DATA_MAP(CDomainLicensesPage)
  1897. DDX_Control(pDX, IDC_LICENSE_LIST, m_LicenseList);
  1898. //}}AFX_DATA_MAP
  1899. } // end CDomainLicensesPage::DoDataExchange
  1900. #ifdef _DEBUG
  1901. /////////////////////////////////////
  1902. // F'N: CDomainLicensesPage::AssertValid
  1903. //
  1904. void CDomainLicensesPage::AssertValid() const
  1905. {
  1906. CFormView::AssertValid();
  1907. } // end CDomainLicensesPage::AssertValid
  1908. //////////////////////////////
  1909. // F'N: CDomainLicensesPage::Dump
  1910. //
  1911. void CDomainLicensesPage::Dump(CDumpContext& dc) const
  1912. {
  1913. CFormView::Dump(dc);
  1914. } // end CDomainLicensesPage::Dump
  1915. #endif //_DEBUG
  1916. /////////////////////////////////////
  1917. // F'N: CDomainLicensesPage::OnSize
  1918. //
  1919. void CDomainLicensesPage::OnSize(UINT nType, int cx, int cy)
  1920. {
  1921. RECT rect;
  1922. GetClientRect(&rect);
  1923. rect.top += LIST_TOP_OFFSET;
  1924. if(m_LicenseList.GetSafeHwnd())
  1925. m_LicenseList.MoveWindow(&rect, TRUE);
  1926. // CFormView::OnSize(nType, cx, cy);
  1927. } // end CDomainLicensesPage::OnSize
  1928. static ColumnDef LicenseColumns[] = {
  1929. CD_SERVER,
  1930. CD_LICENSE_DESC,
  1931. CD_LICENSE_REG,
  1932. CD_USERCOUNT,
  1933. CD_POOLCOUNT,
  1934. CD_LICENSE_NUM,
  1935. };
  1936. #define NUM_DOMAIN_LICENSE_COLUMNS sizeof(LicenseColumns)/sizeof(ColumnDef)
  1937. /////////////////////////////////////
  1938. // F'N: CDomainLicensesPage::OnInitialUpdate
  1939. //
  1940. void CDomainLicensesPage::OnInitialUpdate()
  1941. {
  1942. CFormView::OnInitialUpdate();
  1943. BuildImageList(); // builds the image list for the list control
  1944. CString columnString;
  1945. for(int col = 0; col < NUM_DOMAIN_LICENSE_COLUMNS; col++) {
  1946. columnString.LoadString(LicenseColumns[col].stringID);
  1947. m_LicenseList.InsertColumn(col, columnString, LicenseColumns[col].format, LicenseColumns[col].width, col);
  1948. }
  1949. m_CurrentSortColumn = AS_LICENSE_COL_SERVER;
  1950. } // end CDomainLicensesPage::OnInitialUpdate
  1951. /////////////////////////////////////
  1952. // F'N: CDomainLicensePage::BuildImageList
  1953. //
  1954. // - calls m_ImageList.Create(..) to create the image list
  1955. // - calls AddIconToImageList(..) to add the icons themselves and save
  1956. // off their indices
  1957. // - attaches the image list to the list ctrl
  1958. //
  1959. void CDomainLicensesPage::BuildImageList()
  1960. {
  1961. m_ImageList.Create(16, 16, TRUE, 5, 0);
  1962. m_idxBase = AddIconToImageList(IDI_BASE);
  1963. m_idxBump = AddIconToImageList(IDI_BUMP);
  1964. m_idxEnabler = AddIconToImageList(IDI_ENABLER);
  1965. m_idxUnknown = AddIconToImageList(IDI_UNKNOWN);
  1966. m_LicenseList.SetImageList(&m_ImageList, LVSIL_SMALL);
  1967. } // end CDomainLicensesPage::BuildImageList
  1968. /////////////////////////////////////////
  1969. // F'N: CDomainLicensesPage::AddIconToImageList
  1970. //
  1971. // - loads the appropriate icon, adds it to m_ImageList, and returns
  1972. // the newly-added icon's index in the image list
  1973. //
  1974. int CDomainLicensesPage::AddIconToImageList(int iconID)
  1975. {
  1976. HICON hIcon = ::LoadIcon(AfxGetResourceHandle(), MAKEINTRESOURCE(iconID));
  1977. return m_ImageList.Add(hIcon);
  1978. } // end CDomainLicensesPage::AddIconToImageList
  1979. /////////////////////////////////////
  1980. // F'N: CDomainLicensesPage::Reset
  1981. //
  1982. void CDomainLicensesPage::Reset(void *pDomain)
  1983. {
  1984. ASSERT(pDomain);
  1985. m_pDomain = (CDomain*)pDomain;
  1986. DisplayLicenses();
  1987. } // end CDomainLicensesPage::Reset
  1988. /////////////////////////////////////
  1989. // F'N: CDomainLicensesPage::AddServer
  1990. //
  1991. void CDomainLicensesPage::AddServer(CServer *pServer)
  1992. {
  1993. ASSERT(pServer);
  1994. // Add the Server's licenses to the list
  1995. if(AddServerToList(pServer)) {
  1996. // Sort the list
  1997. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_LICENSES, &m_LicenseList, m_CurrentSortColumn, m_bSortAscending);
  1998. }
  1999. } // end F'N: CDomainLicensesPage::AddServer
  2000. /////////////////////////////////////
  2001. // F'N: CDomainLicensesPage::RemoveServer
  2002. //
  2003. void CDomainLicensesPage::RemoveServer(CServer *pServer)
  2004. {
  2005. ASSERT(pServer);
  2006. // If the server isn't in the current domain, there's nothing to do
  2007. if(m_pDomain != pServer->GetDomain()) return;
  2008. int ItemCount = m_LicenseList.GetItemCount();
  2009. // We need to go through the list backward so that we can remove
  2010. // more than one item without the item numbers getting messed up
  2011. for(int item = ItemCount; item; item--) {
  2012. CLicense *pLicense = (CLicense*)m_LicenseList.GetItemData(item-1);
  2013. CServer *pListServer = pLicense->GetServer();
  2014. if(pListServer == pServer) {
  2015. m_LicenseList.DeleteItem(item-1);
  2016. pServer->ClearAllSelected();
  2017. }
  2018. }
  2019. } // end CDomainLicensesPage::RemoveServer
  2020. //////////////////////////////
  2021. // F'N: CDomainLicensesPage::UpdateServer
  2022. //
  2023. void CDomainLicensesPage::UpdateServer(CServer *pServer)
  2024. {
  2025. ASSERT(pServer);
  2026. // If the server isn't in the current domain, there's nothing to do
  2027. if(m_pDomain != pServer->GetDomain()) return;
  2028. if(pServer->IsState(SS_DISCONNECTING))
  2029. RemoveServer(pServer);
  2030. if(pServer->IsState(SS_GOOD))
  2031. AddServer(pServer);
  2032. } // end CDomainLicensesPage::UpdateServer
  2033. /////////////////////////////////////
  2034. // F'N: CDomainLicensesPage::AddServerToList
  2035. //
  2036. BOOL CDomainLicensesPage::AddServerToList(CServer *pServer)
  2037. {
  2038. ASSERT(pServer);
  2039. // If the server isn't in the current domain, there's nothing to do
  2040. if(m_pDomain != pServer->GetDomain()) return FALSE;
  2041. int item;
  2042. pServer->LockLicenseList();
  2043. // Get a pointer to the Server's list of licenses
  2044. CObList *pLicenseList = pServer->GetLicenseList();
  2045. // Iterate through the License list
  2046. POSITION pos = pLicenseList->GetHeadPosition();
  2047. while(pos) {
  2048. CLicense *pLicense = (CLicense*)pLicenseList->GetNext(pos);
  2049. //////////////////////
  2050. // Fill in the columns
  2051. //////////////////////
  2052. int WhichIcon;
  2053. switch(pLicense->GetClass()) {
  2054. case LicenseBase:
  2055. WhichIcon = m_idxBase;
  2056. break;
  2057. case LicenseBump:
  2058. WhichIcon = m_idxBump;
  2059. break;
  2060. case LicenseEnabler:
  2061. WhichIcon = m_idxEnabler;
  2062. break;
  2063. case LicenseUnknown:
  2064. WhichIcon = m_idxUnknown;
  2065. break;
  2066. }
  2067. // Server Name
  2068. item = m_LicenseList.InsertItem(m_LicenseList.GetItemCount(), pServer->GetName(), WhichIcon);
  2069. // Description
  2070. m_LicenseList.SetItemText(item, AS_LICENSE_COL_DESCRIPTION, pLicense->GetDescription());
  2071. // Registered
  2072. CString RegString;
  2073. RegString.LoadString(pLicense->IsRegistered() ? IDS_YES : IDS_NO);
  2074. m_LicenseList.SetItemText(item, AS_LICENSE_COL_REGISTERED, RegString);
  2075. BOOL bUnlimited = (pLicense->GetClass() == LicenseBase
  2076. && pLicense->GetTotalCount() == 4095
  2077. && pServer->GetCTXVersionNum() == 0x00000040);
  2078. // User (Total) Count
  2079. CString CountString;
  2080. if(bUnlimited)
  2081. CountString.LoadString(IDS_UNLIMITED);
  2082. else
  2083. CountString.Format(TEXT("%lu"), pLicense->GetTotalCount());
  2084. m_LicenseList.SetItemText(item, AS_LICENSE_COL_USERCOUNT, CountString);
  2085. // Pool Count
  2086. if(bUnlimited)
  2087. CountString.LoadString(IDS_NOT_APPLICABLE);
  2088. else
  2089. CountString.Format(TEXT("%lu"), pLicense->GetPoolCount());
  2090. m_LicenseList.SetItemText(item, AS_LICENSE_COL_POOLCOUNT, CountString);
  2091. // License Number
  2092. m_LicenseList.SetItemText(item, AS_LICENSE_COL_NUMBER, pLicense->GetLicenseNumber());
  2093. m_LicenseList.SetItemData(item, (DWORD_PTR)pLicense);
  2094. } // end while(pos)
  2095. m_LicenseList.SetItemState( 0 , LVIS_FOCUSED | LVIS_SELECTED , LVIS_FOCUSED | LVIS_SELECTED );
  2096. pServer->UnlockLicenseList();
  2097. return TRUE;
  2098. } // end CDomainLicensesPage::AddServerToList
  2099. /////////////////////////////////////
  2100. // F'N: CDomainLicensesPage::DisplayLicenses
  2101. //
  2102. void CDomainLicensesPage::DisplayLicenses()
  2103. {
  2104. // Clear out the list control
  2105. m_LicenseList.DeleteAllItems();
  2106. // Get a pointer to the document's list of servers
  2107. CObList* pServerList = ((CWinAdminDoc*)GetDocument())->GetServerList();
  2108. ((CWinAdminDoc*)GetDocument())->LockServerList();
  2109. // Iterate through the server list
  2110. POSITION pos = pServerList->GetHeadPosition();
  2111. while(pos) {
  2112. CServer *pServer = (CServer*)pServerList->GetNext(pos);
  2113. AddServerToList(pServer);
  2114. }
  2115. ((CWinAdminDoc*)GetDocument())->UnlockServerList();
  2116. } // end CDomainLicensesPage::DisplayLicenses
  2117. /////////////////////////////////////
  2118. // F'N: CDomainLicensesPage::OnColumnclick
  2119. //
  2120. void CDomainLicensesPage::OnColumnclick(NMHDR* pNMHDR, LRESULT* pResult)
  2121. {
  2122. NM_LISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR;
  2123. // TODO: Add your control notification handler code here
  2124. // If the sort column hasn't changed, flip the ascending mode.
  2125. if(m_CurrentSortColumn == pNMListView->iSubItem)
  2126. m_bSortAscending = !m_bSortAscending;
  2127. else // New sort column, start in ascending mode
  2128. m_bSortAscending = TRUE;
  2129. m_CurrentSortColumn = pNMListView->iSubItem;
  2130. SortByColumn(VIEW_DOMAIN, PAGE_DOMAIN_LICENSES, &m_LicenseList, m_CurrentSortColumn, m_bSortAscending);
  2131. *pResult = 0;
  2132. } // end CDomainLicensesPage::OnColumnclick
  2133. void CDomainUsersPage::OnSetfocusUserList(NMHDR* pNMHDR, LRESULT* pResult)
  2134. {
  2135. ODS( L"CDomainUsersPage::OnSetfocusUserList\n" );
  2136. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  2137. m_UserList.Invalidate();
  2138. pDoc->RegisterLastFocus( PAGED_ITEM );
  2139. *pResult = 0;
  2140. }
  2141. void CDomainProcessesPage::OnSetfocusProcessList(NMHDR* pNMHDR, LRESULT* pResult)
  2142. {
  2143. ODS( L"CDomainProcessesPage::OnSetfocusProcessList\n" );
  2144. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  2145. m_ProcessList.Invalidate( );
  2146. pDoc->RegisterLastFocus( PAGED_ITEM );
  2147. *pResult = 0;
  2148. }
  2149. void CDomainWinStationsPage::OnSetfocusWinstationList(NMHDR* pNMHDR, LRESULT* pResult)
  2150. {
  2151. ODS( L"CDomainWinStationsPage::OnSetfocusWinstationList\n" );
  2152. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  2153. m_StationList.Invalidate( );
  2154. pDoc->RegisterLastFocus( PAGED_ITEM );
  2155. *pResult = 0;
  2156. }
  2157. void CDomainServersPage::OnSetfocusServerList(NMHDR* pNMHDR, LRESULT* pResult)
  2158. {
  2159. ODS( L"CDomainServersPage::OnSetfocusServerList\n" );
  2160. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  2161. m_ServerList.Invalidate( );
  2162. pDoc->RegisterLastFocus( PAGED_ITEM );
  2163. *pResult = 0;
  2164. }
  2165. void CDomainLicensesPage::OnSetfocusLicenseList(NMHDR* pNMHDR, LRESULT* pResult)
  2166. {
  2167. ODS( L"CDomainLicensesPage::OnSetfocusLicenseList\n" );
  2168. CWinAdminDoc *pDoc = (CWinAdminDoc*)GetDocument();
  2169. m_LicenseList.Invalidate( );
  2170. pDoc->RegisterLastFocus( PAGED_ITEM );
  2171. *pResult = 0;
  2172. }
  2173. void CDomainUsersPage::OnKillfocusUserList(NMHDR* pNMHDR, LRESULT* pResult)
  2174. {
  2175. *pResult = 0;
  2176. m_UserList.Invalidate( );
  2177. }
  2178. void CDomainProcessesPage::OnKillfocusProcessList(NMHDR* pNMHDR, LRESULT* pResult)
  2179. {
  2180. *pResult = 0;
  2181. m_ProcessList.Invalidate( );
  2182. }
  2183. void CDomainWinStationsPage::OnKillfocusWinstationList(NMHDR* pNMHDR, LRESULT* pResult)
  2184. {
  2185. *pResult = 0;
  2186. m_StationList.Invalidate( );
  2187. }
  2188. void CDomainServersPage::OnKillfocusServerList(NMHDR* pNMHDR, LRESULT* pResult)
  2189. {
  2190. *pResult = 0;
  2191. m_ServerList.Invalidate( );
  2192. }
  2193. void CDomainLicensesPage::OnKillfocusLicenseList(NMHDR* pNMHDR, LRESULT* pResult)
  2194. {
  2195. *pResult = 0;
  2196. m_LicenseList.Invalidate( );
  2197. }