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

854 lines
16 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. prdppgu.cpp
  5. Abstract:
  6. Product property page (users) implementation.
  7. Author:
  8. Don Ryan (donryan) 02-Feb-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 30-Jan-1996
  13. o Added new element to LV_COLUMN_ENTRY to differentiate the string
  14. used for the column header from the string used in the menus
  15. (so that the menu option can contain hot keys).
  16. --*/
  17. #include "stdafx.h"
  18. #include "llsmgr.h"
  19. #include "prdppgu.h"
  20. #include "usrpsht.h"
  21. #define LVID_USER 0
  22. #define LVID_LAST_USED 1
  23. #define LVID_TOTAL_USED 2
  24. #define LVCX_USER 40
  25. #define LVCX_LAST_USED 30
  26. #define LVCX_TOTAL_USED -1
  27. static LV_COLUMN_INFO g_userColumnInfo = {
  28. 0, 0, 3,
  29. {{LVID_USER, IDS_USER, 0, LVCX_USER },
  30. {LVID_LAST_USED, IDS_LAST_DATE_USED, 0, LVCX_LAST_USED },
  31. {LVID_TOTAL_USED, IDS_USAGE_COUNT, 0, LVCX_TOTAL_USED}},
  32. };
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char BASED_CODE THIS_FILE[] = __FILE__;
  36. #endif
  37. IMPLEMENT_DYNCREATE(CProductPropertyPageUsers, CPropertyPage)
  38. BEGIN_MESSAGE_MAP(CProductPropertyPageUsers, CPropertyPage)
  39. //{{AFX_MSG_MAP(CProductPropertyPageUsers)
  40. ON_BN_CLICKED(IDC_PP_PRODUCT_USERS_DELETE, OnDelete)
  41. ON_NOTIFY(NM_DBLCLK, IDC_PP_PRODUCT_USERS_USERS, OnDblClkUsers)
  42. ON_NOTIFY(NM_RETURN, IDC_PP_PRODUCT_USERS_USERS, OnReturnUsers)
  43. ON_NOTIFY(NM_SETFOCUS, IDC_PP_PRODUCT_USERS_USERS, OnSetFocusUsers)
  44. ON_NOTIFY(NM_KILLFOCUS, IDC_PP_PRODUCT_USERS_USERS, OnKillFocusUsers)
  45. ON_NOTIFY(LVN_COLUMNCLICK, IDC_PP_PRODUCT_USERS_USERS, OnColumnClickUsers)
  46. ON_NOTIFY(LVN_GETDISPINFO, IDC_PP_PRODUCT_USERS_USERS, OnGetDispInfoUsers)
  47. ON_WM_DESTROY()
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. CProductPropertyPageUsers::CProductPropertyPageUsers()
  51. : CPropertyPage(CProductPropertyPageUsers::IDD)
  52. /*++
  53. Routine Description:
  54. Constructor for product property page (users).
  55. Arguments:
  56. None.
  57. Return Values:
  58. None.
  59. --*/
  60. {
  61. //{{AFX_DATA_INIT(CProductPropertyPageUsers)
  62. //}}AFX_DATA_INIT
  63. m_pProduct = NULL;
  64. m_pUpdateHint = NULL;
  65. m_bUserProperties = FALSE;
  66. m_bAreCtrlsInitialized = FALSE;
  67. }
  68. CProductPropertyPageUsers::~CProductPropertyPageUsers()
  69. /*++
  70. Routine Description:
  71. Destructor for product property page (users).
  72. Arguments:
  73. None.
  74. Return Values:
  75. None.
  76. --*/
  77. {
  78. //
  79. // Nothing to do here.
  80. //
  81. }
  82. void CProductPropertyPageUsers::DoDataExchange(CDataExchange* pDX)
  83. /*++
  84. Routine Description:
  85. Called by framework to exchange dialog data.
  86. Arguments:
  87. pDX - data exchange object.
  88. Return Values:
  89. None.
  90. --*/
  91. {
  92. CPropertyPage::DoDataExchange(pDX);
  93. //{{AFX_DATA_MAP(CProductPropertyPageUsers)
  94. DDX_Control(pDX, IDC_PP_PRODUCT_USERS_DELETE, m_delBtn);
  95. DDX_Control(pDX, IDC_PP_PRODUCT_USERS_USERS, m_userList);
  96. //}}AFX_DATA_MAP
  97. }
  98. void CProductPropertyPageUsers::InitCtrls()
  99. /*++
  100. Routine Description:
  101. Initializes property page controls.
  102. Arguments:
  103. None.
  104. Return Values:
  105. None.
  106. --*/
  107. {
  108. m_userList.SetFocus();
  109. m_delBtn.EnableWindow(FALSE);
  110. m_bAreCtrlsInitialized = TRUE;
  111. ::LvInitColumns(&m_userList, &g_userColumnInfo);
  112. }
  113. void
  114. CProductPropertyPageUsers::InitPage(
  115. CProduct* pProduct,
  116. DWORD* pUpdateHint,
  117. BOOL bUserProperties
  118. )
  119. /*++
  120. Routine Description:
  121. Initializes property page.
  122. Arguments:
  123. pProduct - product object.
  124. pUpdateHint - update hint.
  125. bUserProperties - to recurse or not.
  126. Return Values:
  127. None.
  128. --*/
  129. {
  130. ASSERT(pUpdateHint);
  131. VALIDATE_OBJECT(pProduct, CProduct);
  132. m_pProduct = pProduct;
  133. m_pUpdateHint = pUpdateHint;
  134. m_bUserProperties = bUserProperties;
  135. }
  136. void CProductPropertyPageUsers::AbortPageIfNecessary()
  137. /*++
  138. Routine Description:
  139. Displays status and aborts if connection lost.
  140. Arguments:
  141. None.
  142. Return Values:
  143. None.
  144. --*/
  145. {
  146. theApp.DisplayLastStatus();
  147. if (IsConnectionDropped(LlsGetLastStatus()))
  148. {
  149. AbortPage(); // bail...
  150. }
  151. }
  152. void CProductPropertyPageUsers::AbortPage()
  153. /*++
  154. Routine Description:
  155. Aborts property page.
  156. Arguments:
  157. None.
  158. Return Values:
  159. None.
  160. --*/
  161. {
  162. *m_pUpdateHint = UPDATE_INFO_ABORT;
  163. GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
  164. }
  165. BOOL CProductPropertyPageUsers::OnInitDialog()
  166. /*++
  167. Routine Description:
  168. Message handler for WM_INITDIALOG.
  169. Arguments:
  170. None.
  171. Return Values:
  172. Returns false if focus set to control manually.
  173. --*/
  174. {
  175. CPropertyPage::OnInitDialog();
  176. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  177. return TRUE;
  178. }
  179. void CProductPropertyPageUsers::OnDestroy()
  180. /*++
  181. Routine Description:
  182. Message handler for WM_DESTROY.
  183. Arguments:
  184. None.
  185. Return Values:
  186. None.
  187. --*/
  188. {
  189. ::LvReleaseObArray(&m_userList); // release now...
  190. CPropertyPage::OnDestroy();
  191. }
  192. BOOL CProductPropertyPageUsers::OnSetActive()
  193. /*++
  194. Routine Description:
  195. Activates property page.
  196. Arguments:
  197. None.
  198. Return Values:
  199. Returns true if focus accepted.
  200. --*/
  201. {
  202. BOOL bIsActivated;
  203. bIsActivated = CPropertyPage::OnSetActive();
  204. if (FALSE != bIsActivated)
  205. {
  206. if (IsUserInfoUpdated(*m_pUpdateHint) && !RefreshCtrls())
  207. {
  208. AbortPageIfNecessary(); // display error...
  209. }
  210. }
  211. return bIsActivated;
  212. }
  213. BOOL CProductPropertyPageUsers::RefreshCtrls()
  214. /*++
  215. Routine Description:
  216. Refreshs property page controls.
  217. Arguments:
  218. None.
  219. Return Values:
  220. Returns true if controls refreshed successfully.
  221. --*/
  222. {
  223. VALIDATE_OBJECT(m_pProduct, CProduct);
  224. BOOL bIsRefreshed = FALSE;
  225. VARIANT va;
  226. VariantInit(&va);
  227. BeginWaitCursor(); // hourglass...
  228. CStatistics* pStatistics = (CStatistics*)MKOBJ(m_pProduct->GetStatistics(va));
  229. if (pStatistics)
  230. {
  231. VALIDATE_OBJECT(pStatistics, CStatistics);
  232. bIsRefreshed = ::LvRefreshObArray(
  233. &m_userList,
  234. &g_userColumnInfo,
  235. pStatistics->m_pObArray
  236. );
  237. pStatistics->InternalRelease(); // add ref'd individually...
  238. }
  239. if (!bIsRefreshed)
  240. {
  241. ::LvReleaseObArray(&m_userList); // reset list now...
  242. }
  243. EndWaitCursor(); // hourglass...
  244. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  245. return bIsRefreshed;
  246. }
  247. void CProductPropertyPageUsers::OnDelete()
  248. /*++
  249. Routine Description:
  250. Revokes licenses from user.
  251. Arguments:
  252. None.
  253. Return Values:
  254. None.
  255. --*/
  256. {
  257. CStatistic* pStatistic;
  258. pStatistic = (CStatistic*)::LvGetSelObj(&m_userList);
  259. if (NULL != pStatistic)
  260. {
  261. VALIDATE_OBJECT(pStatistic, CStatistic);
  262. CString strConfirm;
  263. AfxFormatString2(
  264. strConfirm,
  265. IDP_CONFIRM_REVOKE_LICENSE,
  266. pStatistic->m_strEntry,
  267. m_pProduct->m_strName
  268. );
  269. if (AfxMessageBox(strConfirm, MB_YESNO) == IDYES)
  270. {
  271. NTSTATUS NtStatus;
  272. BeginWaitCursor(); // hourglass...
  273. NtStatus = ::LlsUserProductDelete(
  274. LlsGetActiveHandle(),
  275. MKSTR(pStatistic->m_strEntry),
  276. MKSTR(m_pProduct->m_strName)
  277. );
  278. EndWaitCursor(); // hourglass...
  279. if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND)
  280. NtStatus = STATUS_SUCCESS;
  281. LlsSetLastStatus(NtStatus); // called api...
  282. if (NT_SUCCESS(NtStatus))
  283. {
  284. *m_pUpdateHint |= UPDATE_LICENSE_REVOKED;
  285. if (!RefreshCtrls())
  286. {
  287. AbortPageIfNecessary(); // display error...
  288. }
  289. }
  290. else
  291. {
  292. AbortPageIfNecessary(); // display error...
  293. }
  294. }
  295. }
  296. }
  297. void CProductPropertyPageUsers::OnDblClkUsers(NMHDR* pNMHDR, LRESULT* pResult)
  298. /*++
  299. Routine Description:
  300. Notification handler for NM_DBLCLK.
  301. Arguments:
  302. pNMHDR - notification header.
  303. pResult - return code.
  304. Return Values:
  305. None.
  306. --*/
  307. {
  308. UNREFERENCED_PARAMETER(pNMHDR);
  309. ViewUserProperties();
  310. ASSERT(NULL != pResult);
  311. *pResult = 0;
  312. }
  313. void CProductPropertyPageUsers::OnReturnUsers(NMHDR* pNMHDR, LRESULT* pResult)
  314. /*++
  315. Routine Description:
  316. Notification handler for NM_RETURN.
  317. Arguments:
  318. pNMHDR - notification header.
  319. pResult - return code.
  320. Return Values:
  321. None.
  322. --*/
  323. {
  324. UNREFERENCED_PARAMETER(pNMHDR);
  325. ViewUserProperties();
  326. ASSERT(NULL != pResult);
  327. *pResult = 0;
  328. }
  329. void CProductPropertyPageUsers::OnSetFocusUsers(NMHDR* pNMHDR, LRESULT* pResult)
  330. /*++
  331. Routine Description:
  332. Notification handler for NM_SETFOCUS.
  333. Arguments:
  334. pNMHDR - notification header.
  335. pResult - return code.
  336. Return Values:
  337. None.
  338. --*/
  339. {
  340. UNREFERENCED_PARAMETER(pNMHDR);
  341. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  342. ASSERT(NULL != pResult);
  343. *pResult = 0;
  344. }
  345. void CProductPropertyPageUsers::OnKillFocusUsers(NMHDR* pNMHDR, LRESULT* pResult)
  346. /*++
  347. Routine Description:
  348. Notification handler for NM_KILLFOCUS.
  349. Arguments:
  350. pNMHDR - notification header.
  351. pResult - return code.
  352. Return Values:
  353. None.
  354. --*/
  355. {
  356. UNREFERENCED_PARAMETER(pNMHDR);
  357. ::LvSelObjIfNecessary(&m_userList); // ensure selection...
  358. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  359. ASSERT(NULL != pResult);
  360. *pResult = 0;
  361. }
  362. BOOL CProductPropertyPageUsers::OnCommand(WPARAM wParam, LPARAM lParam)
  363. /*++
  364. Routine Description:
  365. Message handler for WM_COMMAND.
  366. Arguments:
  367. wParam - message specific.
  368. lParam - message specific.
  369. Return Values:
  370. Returns true if message processed.
  371. --*/
  372. {
  373. if (wParam == ID_INIT_CTRLS)
  374. {
  375. if (!m_bAreCtrlsInitialized)
  376. {
  377. InitCtrls();
  378. if (!RefreshCtrls())
  379. {
  380. AbortPageIfNecessary(); // display error...
  381. }
  382. }
  383. ::SafeEnableWindow(
  384. &m_delBtn,
  385. &m_userList,
  386. CDialog::GetFocus(),
  387. m_userList.GetItemCount()
  388. );
  389. return TRUE; // processed...
  390. }
  391. return CDialog::OnCommand(wParam, lParam);
  392. }
  393. void CProductPropertyPageUsers::OnColumnClickUsers(NMHDR* pNMHDR, LRESULT* pResult)
  394. /*++
  395. Routine Description:
  396. Notification handler for LVN_COLUMNCLICK.
  397. Arguments:
  398. pNMHDR - notification header.
  399. pResult - return code.
  400. Return Values:
  401. None.
  402. --*/
  403. {
  404. g_userColumnInfo.bSortOrder = GetKeyState(VK_CONTROL) < 0;
  405. ASSERT(NULL != pNMHDR);
  406. g_userColumnInfo.nSortedItem = ((NM_LISTVIEW*)pNMHDR)->iSubItem;
  407. m_userList.SortItems(CompareProductUsers, 0); // use column info
  408. ASSERT(NULL != pResult);
  409. *pResult = 0;
  410. }
  411. void CProductPropertyPageUsers::ViewUserProperties()
  412. /*++
  413. Routine Description:
  414. Recurse into user property page.
  415. Arguments:
  416. None.
  417. Return Values:
  418. None.
  419. --*/
  420. {
  421. CStatistic* pStatistic;
  422. if (!m_bUserProperties)
  423. {
  424. ::MessageBeep(MB_OK);
  425. return; // bail if recursion disabled...
  426. }
  427. pStatistic = (CStatistic*)::LvGetSelObj(&m_userList);
  428. if (NULL != pStatistic)
  429. {
  430. VALIDATE_OBJECT(pStatistic, CStatistic);
  431. CUser* pUser = new CUser(NULL, pStatistic->m_strEntry);
  432. if (pUser && pUser->Refresh())
  433. {
  434. CString strTitle;
  435. AfxFormatString1(strTitle, IDS_PROPERTIES_OF, pUser->m_strName);
  436. CUserPropertySheet userProperties(strTitle);
  437. userProperties.InitPages(pUser, FALSE);
  438. userProperties.DoModal();
  439. *m_pUpdateHint |= userProperties.m_fUpdateHint;
  440. if (IsUpdateAborted(userProperties.m_fUpdateHint))
  441. {
  442. AbortPage(); // don't display error...
  443. }
  444. else if (IsUserInfoUpdated(userProperties.m_fUpdateHint) && !RefreshCtrls())
  445. {
  446. AbortPageIfNecessary(); // display error...
  447. }
  448. }
  449. else
  450. {
  451. AbortPageIfNecessary(); // display error...
  452. }
  453. if (pUser)
  454. pUser->InternalRelease(); // delete object...
  455. }
  456. }
  457. void CProductPropertyPageUsers::OnGetDispInfoUsers(NMHDR* pNMHDR, LRESULT* pResult)
  458. /*++
  459. Routine Description:
  460. Notification handler for LVN_GETDISPINFO.
  461. Arguments:
  462. pNMHDR - notification header.
  463. pResult - return code.
  464. Return Values:
  465. None.
  466. --*/
  467. {
  468. ASSERT(NULL != pNMHDR);
  469. LV_ITEM* plvItem = &((LV_DISPINFO*)pNMHDR)->item;
  470. ASSERT(plvItem);
  471. CStatistic* pStatistic = (CStatistic*)plvItem->lParam;
  472. VALIDATE_OBJECT(pStatistic, CStatistic);
  473. switch (plvItem->iSubItem)
  474. {
  475. case LVID_USER:
  476. plvItem->iImage = pStatistic->m_bIsValid ? BMPI_USER : BMPI_VIOLATION;
  477. lstrcpyn(plvItem->pszText, pStatistic->m_strEntry, plvItem->cchTextMax);
  478. break;
  479. case LVID_LAST_USED:
  480. {
  481. BSTR bstrDateLastUsed = pStatistic->GetLastUsedString();
  482. if( bstrDateLastUsed != NULL )
  483. {
  484. lstrcpyn(plvItem->pszText, bstrDateLastUsed, plvItem->cchTextMax);
  485. SysFreeString(bstrDateLastUsed);
  486. }
  487. else
  488. {
  489. plvItem->pszText[0] = L'\0';
  490. }
  491. }
  492. break;
  493. case LVID_TOTAL_USED:
  494. {
  495. CString strLabel;
  496. strLabel.Format(_T("%ld"), pStatistic->GetTotalUsed());
  497. lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
  498. }
  499. break;
  500. }
  501. ASSERT(NULL != pResult);
  502. *pResult = 0;
  503. }
  504. int CALLBACK CompareProductUsers(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  505. /*++
  506. Routine Description:
  507. Notification handler for LVM_SORTITEMS.
  508. Arguments:
  509. lParam1 - object to sort.
  510. lParam2 - object to sort.
  511. lParamSort - sort criteria.
  512. Return Values:
  513. Same as lstrcmp.
  514. --*/
  515. {
  516. UNREFERENCED_PARAMETER(lParamSort);
  517. #define pStatistic1 ((CStatistic*)lParam1)
  518. #define pStatistic2 ((CStatistic*)lParam2)
  519. VALIDATE_OBJECT(pStatistic1, CStatistic);
  520. VALIDATE_OBJECT(pStatistic2, CStatistic);
  521. int iResult;
  522. switch (g_userColumnInfo.nSortedItem)
  523. {
  524. case LVID_USER:
  525. iResult = pStatistic1->m_strEntry.CompareNoCase(pStatistic2->m_strEntry);
  526. break;
  527. case LVID_LAST_USED:
  528. iResult = pStatistic1->m_lLastUsed - pStatistic2->m_lLastUsed;
  529. break;
  530. case LVID_TOTAL_USED:
  531. iResult = pStatistic1->GetTotalUsed() - pStatistic2->GetTotalUsed();
  532. break;
  533. default:
  534. iResult = 0;
  535. break;
  536. }
  537. return g_userColumnInfo.bSortOrder ? -iResult : iResult;
  538. }