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.

732 lines
12 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. srvppgp.cpp
  5. Abstract:
  6. Server property page (services) implementation.
  7. Author:
  8. Don Ryan (donryan) 05-Feb-1995
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. Jeff Parham (jeffparh) 30-Jan-1996
  13. o Fixed to properly abort dialog upon ERROR_ACCESS_DENIED.
  14. o Ported to LlsLocalService API to remove dependencies on configuration
  15. information being in the registry.
  16. --*/
  17. #include "stdafx.h"
  18. #include "llsmgr.h"
  19. #include "srvppgp.h"
  20. #include "lmoddlg.h"
  21. #define LVID_PRODUCT 0
  22. #define LVID_LICENSING_MODE 1
  23. #define LVID_LICENSES_PURCHASED 2
  24. #define LVCX_PRODUCT 40
  25. #define LVCX_LICENSING_MODE 30
  26. #define LVCX_LICENSES_PURCHASED -1
  27. static LV_COLUMN_INFO g_productColumnInfo = {
  28. 0, 0, 3,
  29. {{LVID_PRODUCT, IDS_PRODUCT, 0, LVCX_PRODUCT },
  30. {LVID_LICENSING_MODE, IDS_LICENSING_MODE, 0, LVCX_LICENSING_MODE },
  31. {LVID_LICENSES_PURCHASED, IDS_LICENSES_PURCHASED, 0, LVCX_LICENSES_PURCHASED}},
  32. };
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char BASED_CODE THIS_FILE[] = __FILE__;
  36. #endif
  37. IMPLEMENT_DYNCREATE(CServerPropertyPageProducts, CPropertyPage)
  38. BEGIN_MESSAGE_MAP(CServerPropertyPageProducts, CPropertyPage)
  39. //{{AFX_MSG_MAP(CServerPropertyPageProducts)
  40. ON_BN_CLICKED(IDC_PP_SERVER_PRODUCTS_EDIT, OnEdit)
  41. ON_NOTIFY(NM_DBLCLK, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnDblClkProducts)
  42. ON_NOTIFY(NM_RETURN, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnReturnProducts)
  43. ON_NOTIFY(NM_SETFOCUS, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnSetFocusProducts)
  44. ON_NOTIFY(NM_KILLFOCUS, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnKillFocusProducts)
  45. ON_NOTIFY(LVN_COLUMNCLICK, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnColumnClickProducts)
  46. ON_NOTIFY(LVN_GETDISPINFO, IDC_PP_SERVER_PRODUCTS_PRODUCTS, OnGetDispInfoProducts)
  47. ON_WM_DESTROY()
  48. //}}AFX_MSG_MAP
  49. END_MESSAGE_MAP()
  50. CServerPropertyPageProducts::CServerPropertyPageProducts() :
  51. CPropertyPage(CServerPropertyPageProducts::IDD)
  52. /*++
  53. Routine Description:
  54. Constructor for server property page (products).
  55. Arguments:
  56. None.
  57. Return Values:
  58. None.
  59. --*/
  60. {
  61. //{{AFX_DATA_INIT(CServerPropertyPageProducts)
  62. //}}AFX_DATA_INIT
  63. m_pServer = NULL;
  64. m_pUpdateHint = NULL;
  65. m_bAreCtrlsInitialized = FALSE;
  66. }
  67. CServerPropertyPageProducts::~CServerPropertyPageProducts()
  68. /*++
  69. Routine Description:
  70. Destructor for server property page (products).
  71. Arguments:
  72. None.
  73. Return Values:
  74. None.
  75. --*/
  76. {
  77. //
  78. // Nothing to do here...
  79. //
  80. }
  81. void CServerPropertyPageProducts::DoDataExchange(CDataExchange* pDX)
  82. /*++
  83. Routine Description:
  84. Called by framework to exchange dialog data.
  85. Arguments:
  86. pDX - data exchange object.
  87. Return Values:
  88. None.
  89. --*/
  90. {
  91. CPropertyPage::DoDataExchange(pDX);
  92. //{{AFX_DATA_MAP(CServerPropertyPageProducts)
  93. DDX_Control(pDX, IDC_PP_SERVER_PRODUCTS_EDIT, m_edtBtn);
  94. DDX_Control(pDX, IDC_PP_SERVER_PRODUCTS_PRODUCTS, m_productList);
  95. //}}AFX_DATA_MAP
  96. }
  97. void CServerPropertyPageProducts::InitCtrls()
  98. /*++
  99. Routine Description:
  100. Initializes property page controls.
  101. Arguments:
  102. None.
  103. Return Values:
  104. None.
  105. --*/
  106. {
  107. m_productList.SetFocus();
  108. m_edtBtn.EnableWindow(FALSE);
  109. m_bAreCtrlsInitialized = TRUE;
  110. ::LvInitColumns(&m_productList, &g_productColumnInfo);
  111. }
  112. void CServerPropertyPageProducts::InitPage(CServer* pServer, DWORD* pUpdateHint)
  113. /*++
  114. Routine Description:
  115. Initializes property page.
  116. Arguments:
  117. pServer - Server object.
  118. pUpdateHint - update hint.
  119. Return Values:
  120. None.
  121. --*/
  122. {
  123. ASSERT(pUpdateHint);
  124. VALIDATE_OBJECT(pServer, CServer);
  125. m_pServer = pServer;
  126. m_pUpdateHint = pUpdateHint;
  127. }
  128. void CServerPropertyPageProducts::AbortPageIfNecessary()
  129. /*++
  130. Routine Description:
  131. Displays status and aborts if connection lost.
  132. Arguments:
  133. None.
  134. Return Values:
  135. None.
  136. --*/
  137. {
  138. theApp.DisplayLastStatus();
  139. if ( IsConnectionDropped( LlsGetLastStatus() )
  140. || ( ERROR_ACCESS_DENIED == LlsGetLastStatus() )
  141. || ( STATUS_ACCESS_DENIED == LlsGetLastStatus() ) )
  142. {
  143. AbortPage(); // bail...
  144. }
  145. }
  146. void CServerPropertyPageProducts::AbortPage()
  147. /*++
  148. Routine Description:
  149. Aborts property page.
  150. Arguments:
  151. None.
  152. Return Values:
  153. None.
  154. --*/
  155. {
  156. // *m_pUpdateHint = UPDATE_INFO_ABORT;
  157. GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
  158. }
  159. BOOL CServerPropertyPageProducts::OnInitDialog()
  160. /*++
  161. Routine Description:
  162. Message handler for WM_INITDIALOG.
  163. Arguments:
  164. None.
  165. Return Values:
  166. Returns false if focus set manually.
  167. --*/
  168. {
  169. CPropertyPage::OnInitDialog();
  170. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  171. return TRUE;
  172. }
  173. void CServerPropertyPageProducts::OnDestroy()
  174. /*++
  175. Routine Description:
  176. Message handler for WM_DESTROY.
  177. Arguments:
  178. None.
  179. Return Values:
  180. None.
  181. --*/
  182. {
  183. ::LvReleaseObArray(&m_productList); // release now...
  184. CPropertyPage::OnDestroy();
  185. }
  186. BOOL CServerPropertyPageProducts::OnSetActive()
  187. /*++
  188. Routine Description:
  189. Activates property page.
  190. Arguments:
  191. None.
  192. Return Values:
  193. Returns true if focus accepted.
  194. --*/
  195. {
  196. BOOL bIsActivated;
  197. if (bIsActivated = CPropertyPage::OnSetActive())
  198. {
  199. if (IsServiceInfoUpdated(*m_pUpdateHint) && !RefreshCtrls())
  200. {
  201. AbortPageIfNecessary(); // display error...
  202. }
  203. }
  204. return bIsActivated;
  205. }
  206. BOOL CServerPropertyPageProducts::RefreshCtrls()
  207. /*++
  208. Routine Description:
  209. Refreshs property page controls.
  210. Arguments:
  211. None.
  212. Return Values:
  213. Returns true if controls refreshed successfully.
  214. --*/
  215. {
  216. VALIDATE_OBJECT(m_pServer, CServer);
  217. BOOL bIsRefreshed = FALSE;
  218. VARIANT va;
  219. VariantInit(&va);
  220. BeginWaitCursor(); // hourglass...
  221. CServices* pServices = (CServices*)MKOBJ(m_pServer->GetServices(va));
  222. if (pServices)
  223. {
  224. VALIDATE_OBJECT(pServices, CServices);
  225. bIsRefreshed = ::LvRefreshObArray(
  226. &m_productList,
  227. &g_productColumnInfo,
  228. pServices->m_pObArray
  229. );
  230. pServices->InternalRelease(); // add ref'd individually...
  231. }
  232. if (!bIsRefreshed)
  233. {
  234. ::LvReleaseObArray(&m_productList); // reset list now...
  235. }
  236. EndWaitCursor(); // hourglass...
  237. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  238. return bIsRefreshed;
  239. }
  240. void CServerPropertyPageProducts::OnEdit()
  241. /*++
  242. Routine Description:
  243. View licensing mode of service.
  244. Arguments:
  245. None.
  246. Return Values:
  247. None.
  248. --*/
  249. {
  250. CService* pService;
  251. if (pService = (CService*)::LvGetSelObj(&m_productList))
  252. {
  253. VALIDATE_OBJECT(pService, CService);
  254. CLicensingModeDialog lmodDlg;
  255. lmodDlg.InitDialog(pService);
  256. lmodDlg.DoModal();
  257. *m_pUpdateHint |= lmodDlg.m_fUpdateHint;
  258. if (IsUpdateAborted(lmodDlg.m_fUpdateHint))
  259. {
  260. AbortPage(); // don't display error...
  261. }
  262. else if (IsServiceInfoUpdated(lmodDlg.m_fUpdateHint) && !RefreshCtrls())
  263. {
  264. AbortPageIfNecessary(); // display error...
  265. }
  266. }
  267. }
  268. void CServerPropertyPageProducts::OnDblClkProducts(NMHDR* pNMHDR, LRESULT* pResult)
  269. /*++
  270. Routine Description:
  271. Notification handler for NM_DBLCLK.
  272. Arguments:
  273. pNMHDR - notification header.
  274. pResult - return code.
  275. Return Values:
  276. None.
  277. --*/
  278. {
  279. OnEdit();
  280. *pResult = 0;
  281. }
  282. void CServerPropertyPageProducts::OnReturnProducts(NMHDR* pNMHDR, LRESULT* pResult)
  283. /*++
  284. Routine Description:
  285. Notification handler for NM_RETURN.
  286. Arguments:
  287. pNMHDR - notification header.
  288. pResult - return code.
  289. Return Values:
  290. None.
  291. --*/
  292. {
  293. OnEdit();
  294. *pResult = 0;
  295. }
  296. void CServerPropertyPageProducts::OnSetFocusProducts(NMHDR* pNMHDR, LRESULT* pResult)
  297. /*++
  298. Routine Description:
  299. Notification handler for NM_SETFOCUS.
  300. Arguments:
  301. pNMHDR - notification header.
  302. pResult - return code.
  303. Return Values:
  304. None.
  305. --*/
  306. {
  307. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  308. *pResult = 0;
  309. }
  310. void CServerPropertyPageProducts::OnKillFocusProducts(NMHDR* pNMHDR, LRESULT* pResult)
  311. /*++
  312. Routine Description:
  313. Notification handler for NM_KILLFOCUS.
  314. Arguments:
  315. pNMHDR - notification header.
  316. pResult - return code.
  317. Return Values:
  318. None.
  319. --*/
  320. {
  321. ::LvSelObjIfNecessary(&m_productList); // ensure selection...
  322. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  323. *pResult = 0;
  324. }
  325. BOOL CServerPropertyPageProducts::OnCommand(WPARAM wParam, LPARAM lParam)
  326. /*++
  327. Routine Description:
  328. Message handler for WM_COMMAND.
  329. Arguments:
  330. wParam - message specific.
  331. lParam - message specific.
  332. Return Values:
  333. Returns true if message processed.
  334. --*/
  335. {
  336. if (wParam == ID_INIT_CTRLS)
  337. {
  338. if (!m_bAreCtrlsInitialized)
  339. {
  340. InitCtrls();
  341. if (!RefreshCtrls())
  342. {
  343. AbortPageIfNecessary(); // display error...
  344. }
  345. }
  346. ::SafeEnableWindow(
  347. &m_edtBtn,
  348. &m_productList,
  349. CDialog::GetFocus(),
  350. m_productList.GetItemCount()
  351. );
  352. return TRUE; // processed...
  353. }
  354. return CDialog::OnCommand(wParam, lParam);
  355. }
  356. void CServerPropertyPageProducts::OnColumnClickProducts(NMHDR* pNMHDR, LRESULT* pResult)
  357. /*++
  358. Routine Description:
  359. Notification handler for LVN_COLUMNCLICK.
  360. Arguments:
  361. pNMHDR - notification header.
  362. pResult - return code.
  363. Return Values:
  364. None.
  365. --*/
  366. {
  367. g_productColumnInfo.bSortOrder = GetKeyState(VK_CONTROL) < 0;
  368. g_productColumnInfo.nSortedItem = ((NM_LISTVIEW*)pNMHDR)->iSubItem;
  369. m_productList.SortItems(CompareServerProducts, 0); // use column info
  370. *pResult = 0;
  371. }
  372. void CServerPropertyPageProducts::OnGetDispInfoProducts(NMHDR* pNMHDR, LRESULT* pResult)
  373. /*++
  374. Routine Description:
  375. Notification handler for LVN_GETDISPINFO.
  376. Arguments:
  377. pNMHDR - notification header.
  378. pResult - return code.
  379. Return Values:
  380. None.
  381. --*/
  382. {
  383. CString strLabel;
  384. LV_ITEM* plvItem = &((LV_DISPINFO*)pNMHDR)->item;
  385. CService* pService = (CService*)plvItem->lParam;
  386. VALIDATE_OBJECT(pService, CService);
  387. switch (plvItem->iSubItem)
  388. {
  389. case LVID_PRODUCT:
  390. {
  391. plvItem->iImage = pService->IsPerServer() ? BMPI_PRODUCT_PER_SERVER : BMPI_PRODUCT_PER_SEAT;
  392. BSTR bstrServiceName = pService->GetDisplayName();
  393. lstrcpyn(plvItem->pszText, bstrServiceName, plvItem->cchTextMax);
  394. SysFreeString(bstrServiceName);
  395. }
  396. break;
  397. case LVID_LICENSING_MODE:
  398. strLabel.LoadString(pService->IsPerServer() ? IDS_PER_SERVER : IDS_PER_SEAT);
  399. lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
  400. break;
  401. case LVID_LICENSES_PURCHASED:
  402. if (pService->IsPerServer())
  403. {
  404. strLabel.Format(_T("%ld"), pService->GetPerServerLimit());
  405. }
  406. else
  407. {
  408. strLabel.LoadString(IDS_NOT_APPLICABLE);
  409. }
  410. lstrcpyn(plvItem->pszText, strLabel, plvItem->cchTextMax);
  411. break;
  412. }
  413. *pResult = 0;
  414. }
  415. int CALLBACK CompareServerProducts(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
  416. /*++
  417. Routine Description:
  418. Notification handler for LVM_SORTITEMS.
  419. Arguments:
  420. lParam1 - object to sort.
  421. lParam2 - object to sort.
  422. lParamSort - sort criteria.
  423. Return Values:
  424. Same as lstrcmp.
  425. --*/
  426. {
  427. #define pService1 ((CService*)lParam1)
  428. #define pService2 ((CService*)lParam2)
  429. VALIDATE_OBJECT(pService1, CService);
  430. VALIDATE_OBJECT(pService2, CService);
  431. int iResult;
  432. switch (g_productColumnInfo.nSortedItem)
  433. {
  434. case LVID_PRODUCT:
  435. iResult = pService1->m_strName.CompareNoCase(pService2->m_strName);
  436. break;
  437. case LVID_LICENSING_MODE:
  438. iResult = (DWORD)pService1->IsPerServer() - (DWORD)pService2->IsPerServer();
  439. break;
  440. case LVID_LICENSES_PURCHASED:
  441. iResult = pService1->GetPerServerLimit() - pService2->GetPerServerLimit();
  442. break;
  443. default:
  444. iResult = 0;
  445. break;
  446. }
  447. return g_productColumnInfo.bSortOrder ? -iResult : iResult;
  448. }