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.

883 lines
17 KiB

  1. /*++
  2. Copyright (c) 1994-95 Microsoft Corporation
  3. Module Name:
  4. mapppgs.cpp
  5. Abstract:
  6. Mapping property page (settings) 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 "mapppgs.h"
  20. #include "ausrdlg.h"
  21. #include "mainfrm.h"
  22. static LV_COLUMN_INFO g_userColumnInfo = {0, 0, 1, {0, 0, 0, -1}};
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char BASED_CODE THIS_FILE[] = __FILE__;
  26. #endif
  27. IMPLEMENT_DYNCREATE(CMappingPropertyPageSettings, CPropertyPage)
  28. BEGIN_MESSAGE_MAP(CMappingPropertyPageSettings, CPropertyPage)
  29. //{{AFX_MSG_MAP(CMappingPropertyPageSettings)
  30. ON_BN_CLICKED(IDC_PP_MAPPING_SETTINGS_ADD, OnAdd)
  31. ON_BN_CLICKED(IDC_PP_MAPPING_SETTINGS_DELETE, OnDelete)
  32. ON_NOTIFY(UDN_DELTAPOS, IDC_PP_MAPPING_SETTINGS_SPIN, OnDeltaPosSpin)
  33. ON_NOTIFY(LVN_GETDISPINFO, IDC_PP_MAPPING_SETTINGS_USERS, OnGetDispInfoUsers)
  34. ON_EN_UPDATE(IDC_PP_MAPPING_SETTINGS_LICENSES, OnUpdateQuantity)
  35. ON_WM_DESTROY()
  36. //}}AFX_MSG_MAP
  37. END_MESSAGE_MAP()
  38. CMappingPropertyPageSettings::CMappingPropertyPageSettings()
  39. : CPropertyPage(CMappingPropertyPageSettings::IDD)
  40. /*++
  41. Routine Description:
  42. Constructor for mapping property page (settings).
  43. Arguments:
  44. None.
  45. Return Values:
  46. None.
  47. --*/
  48. {
  49. //{{AFX_DATA_INIT(CMappingPropertyPageSettings)
  50. m_strDescription = _T("");
  51. m_nLicenses = 0;
  52. m_nLicensesMin = 0;
  53. m_strName = _T("");
  54. //}}AFX_DATA_INIT
  55. m_pMapping = NULL;
  56. m_pUpdateHint = NULL;
  57. m_bAreCtrlsInitialized = FALSE;
  58. }
  59. CMappingPropertyPageSettings::~CMappingPropertyPageSettings()
  60. /*++
  61. Routine Description:
  62. Destructor for mapping property page (settings).
  63. Arguments:
  64. None.
  65. Return Values:
  66. None.
  67. --*/
  68. {
  69. //
  70. // Nothing to do here...
  71. //
  72. }
  73. void CMappingPropertyPageSettings::DoDataExchange(CDataExchange* pDX)
  74. /*++
  75. Routine Description:
  76. Called by framework to exchange dialog data.
  77. Arguments:
  78. pDX - data exchange object.
  79. Return Values:
  80. None.
  81. --*/
  82. {
  83. CPropertyPage::DoDataExchange(pDX);
  84. //{{AFX_DATA_MAP(CMappingPropertyPageSettings)
  85. DDX_Control(pDX, IDC_PP_MAPPING_SETTINGS_DESCRIPTION, m_desEdit);
  86. DDX_Control(pDX, IDC_PP_MAPPING_SETTINGS_LICENSES, m_licEdit);
  87. DDX_Control(pDX, IDC_PP_MAPPING_SETTINGS_DELETE, m_delBtn);
  88. DDX_Control(pDX, IDC_PP_MAPPING_SETTINGS_ADD, m_addBtn);
  89. DDX_Control(pDX, IDC_PP_MAPPING_SETTINGS_SPIN, m_spinCtrl);
  90. DDX_Control(pDX, IDC_PP_MAPPING_SETTINGS_USERS, m_userList);
  91. DDX_Text(pDX, IDC_PP_MAPPING_SETTINGS_DESCRIPTION, m_strDescription);
  92. DDX_Text(pDX, IDC_PP_MAPPING_SETTINGS_LICENSES, m_nLicenses);
  93. DDV_MinMaxDWord(pDX, m_nLicenses, m_nLicensesMin, 999999);
  94. DDX_Text(pDX, IDC_PP_MAPPING_SETTINGS_NAME, m_strName);
  95. //}}AFX_DATA_MAP
  96. }
  97. void CMappingPropertyPageSettings::InitCtrls()
  98. /*++
  99. Routine Description:
  100. Initializes property page controls.
  101. Arguments:
  102. None.
  103. Return Values:
  104. None.
  105. --*/
  106. {
  107. m_strName = m_pMapping->m_strName;
  108. m_strDescription = m_pMapping->m_strDescription;
  109. m_nLicenses = m_pMapping->GetInUse();
  110. UpdateData(FALSE); // upload;
  111. m_delBtn.EnableWindow(FALSE);
  112. m_spinCtrl.SetRange(0, UD_MAXVAL);
  113. m_licEdit.LimitText(6);
  114. m_desEdit.LimitText(256);
  115. m_bAreCtrlsInitialized = TRUE;
  116. ::LvInitColumns(&m_userList, &g_userColumnInfo);
  117. }
  118. void CMappingPropertyPageSettings::InitPage(CMapping* pMapping, DWORD* pUpdateHint)
  119. /*++
  120. Routine Description:
  121. Initializes property page.
  122. Arguments:
  123. pMapping - mapping object.
  124. pUpdateHint - update hints.
  125. Return Values:
  126. None.
  127. --*/
  128. {
  129. ASSERT(pUpdateHint);
  130. VALIDATE_OBJECT(pMapping, CMapping);
  131. m_pMapping = pMapping;
  132. m_pUpdateHint = pUpdateHint;
  133. }
  134. void CMappingPropertyPageSettings::AbortPageIfNecessary()
  135. /*++
  136. Routine Description:
  137. Displays status and aborts if connection lost.
  138. Arguments:
  139. None.
  140. Return Values:
  141. None.
  142. --*/
  143. {
  144. theApp.DisplayLastStatus();
  145. if (IsConnectionDropped(LlsGetLastStatus()))
  146. {
  147. AbortPage(); // bail...
  148. }
  149. }
  150. void CMappingPropertyPageSettings::AbortPage()
  151. /*++
  152. Routine Description:
  153. Aborts property page.
  154. Arguments:
  155. None.
  156. Return Values:
  157. None.
  158. --*/
  159. {
  160. *m_pUpdateHint = UPDATE_INFO_ABORT;
  161. GetParent()->PostMessage(WM_COMMAND, IDCANCEL);
  162. }
  163. BOOL CMappingPropertyPageSettings::OnInitDialog()
  164. /*++
  165. Routine Description:
  166. Message handler for WM_INITDIALOG.
  167. Arguments:
  168. None.
  169. Return Values:
  170. Returns false if focus set to control manually.
  171. --*/
  172. {
  173. CPropertyPage::OnInitDialog();
  174. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  175. return TRUE;
  176. }
  177. void CMappingPropertyPageSettings::OnDestroy()
  178. /*++
  179. Routine Description:
  180. Message handler for WM_DESTROY.
  181. Arguments:
  182. None.
  183. Return Values:
  184. None.
  185. --*/
  186. {
  187. ::LvReleaseObArray(&m_userList); // release now...
  188. while (!m_deleteList.IsEmpty())
  189. {
  190. CUser* pUserDel = (CUser*)m_deleteList.RemoveHead();
  191. VALIDATE_OBJECT(pUserDel, CUser);
  192. pUserDel->InternalRelease(); // release now...
  193. }
  194. CPropertyPage::OnDestroy();
  195. }
  196. BOOL CMappingPropertyPageSettings::OnSetActive()
  197. /*++
  198. Routine Description:
  199. Activates property page.
  200. Arguments:
  201. None.
  202. Return Values:
  203. Returns true if focus accepted.
  204. --*/
  205. {
  206. BOOL bIsActivated;
  207. bIsActivated = CPropertyPage::OnSetActive();
  208. if (FALSE != bIsActivated)
  209. {
  210. if (IsGroupInfoUpdated(*m_pUpdateHint) && !RefreshCtrls())
  211. {
  212. AbortPageIfNecessary(); // display error...
  213. }
  214. }
  215. return bIsActivated;
  216. }
  217. void CMappingPropertyPageSettings::OnAdd()
  218. /*++
  219. Routine Description:
  220. Adds users to list.
  221. Arguments:
  222. None.
  223. Return Values:
  224. None.
  225. --*/
  226. {
  227. CObList newUserList;
  228. CAddUsersDialog addDlg;
  229. addDlg.InitDialog(&newUserList);
  230. if (addDlg.DoModal() == IDOK)
  231. {
  232. int nUsers = m_userList.GetItemCount();
  233. while (!newUserList.IsEmpty())
  234. {
  235. CUser* pUser = (CUser*)newUserList.RemoveHead();
  236. VALIDATE_OBJECT(pUser, CUser);
  237. LV_FINDINFO lvFindInfo;
  238. lvFindInfo.flags = LVFI_STRING;
  239. lvFindInfo.psz = MKSTR(pUser->m_strName);
  240. if (m_userList.FindItem(&lvFindInfo, -1) == -1)
  241. {
  242. //
  243. // Check if already deleted once
  244. //
  245. CUser* pUserDel;
  246. POSITION curPos;
  247. POSITION nextPos;
  248. nextPos = m_deleteList.GetHeadPosition();
  249. while (NULL != (curPos = nextPos))
  250. {
  251. pUserDel = (CUser*)m_deleteList.GetNext(nextPos);
  252. VALIDATE_OBJECT(pUserDel, CUser);
  253. if (!pUserDel->m_strName.CompareNoCase(pUser->m_strName))
  254. {
  255. m_deleteList.RemoveAt(curPos);
  256. pUser->InternalRelease(); // release new...
  257. pUser = pUserDel; // replace with old...
  258. break;
  259. }
  260. }
  261. LV_ITEM lvItem;
  262. lvItem.mask = LVIF_TEXT|
  263. LVIF_PARAM|
  264. LVIF_IMAGE;
  265. lvItem.iItem = nUsers++; // append...
  266. lvItem.iSubItem = 0;
  267. lvItem.pszText = LPSTR_TEXTCALLBACK;
  268. lvItem.cchTextMax = LPSTR_TEXTCALLBACK_MAX;
  269. lvItem.iImage = I_IMAGECALLBACK;
  270. lvItem.lParam = (LPARAM)(LPVOID)pUser;
  271. m_userList.InsertItem(&lvItem);
  272. }
  273. else
  274. {
  275. pUser->InternalRelease(); // allocated in add user dialog...
  276. }
  277. }
  278. VERIFY(m_userList.SortItems(CompareUsersInMapping, 0)); // use column info...
  279. ::LvSelObjIfNecessary(&m_userList, TRUE); // ensure selection...
  280. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  281. }
  282. }
  283. void CMappingPropertyPageSettings::OnDelete()
  284. /*++
  285. Routine Description:
  286. Removes users from list.
  287. Arguments:
  288. None.
  289. Return Values:
  290. None.
  291. --*/
  292. {
  293. CUser* pUser;
  294. CMapping* pMapping;
  295. int iItem = -1;
  296. while (NULL != (pUser = (CUser*)::LvGetNextObj(&m_userList, &iItem)))
  297. {
  298. VALIDATE_OBJECT(pUser, CUser);
  299. //
  300. // Only cache users with this mapping as a parent
  301. //
  302. pMapping = (CMapping*)MKOBJ(pUser->GetParent());
  303. if (NULL != pMapping)
  304. {
  305. ASSERT(m_pMapping == pMapping);
  306. pMapping->InternalRelease(); // just checking...
  307. m_deleteList.AddTail(pUser);
  308. }
  309. else
  310. {
  311. pUser->InternalRelease(); // release now...
  312. }
  313. VERIFY(m_userList.DeleteItem(iItem));
  314. iItem = -1;
  315. }
  316. ::LvSelObjIfNecessary(&m_userList, TRUE); // ensure selection...
  317. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  318. }
  319. BOOL CMappingPropertyPageSettings::RefreshCtrls()
  320. /*++
  321. Routine Description:
  322. Refreshs dialog controls.
  323. Arguments:
  324. None.
  325. Return Values:
  326. Returns true if controls refreshed.
  327. --*/
  328. {
  329. VALIDATE_OBJECT(m_pMapping, CMapping);
  330. BOOL bIsRefreshed = FALSE;
  331. VARIANT va;
  332. VariantInit(&va);
  333. BeginWaitCursor(); // hourglass...
  334. CUsers* pUsers = (CUsers*)MKOBJ(m_pMapping->GetUsers(va));
  335. if (pUsers)
  336. {
  337. VALIDATE_OBJECT(pUsers, CUsers);
  338. bIsRefreshed = ::LvRefreshObArray(
  339. &m_userList,
  340. &g_userColumnInfo,
  341. pUsers->m_pObArray
  342. );
  343. pUsers->InternalRelease(); // add ref'd individually...
  344. }
  345. if (!bIsRefreshed)
  346. {
  347. ::LvReleaseObArray(&m_userList); // reset list now...
  348. }
  349. EndWaitCursor(); // hourglass...
  350. PostMessage(WM_COMMAND, ID_INIT_CTRLS);
  351. return bIsRefreshed;
  352. }
  353. BOOL CMappingPropertyPageSettings::OnKillActive()
  354. /*++
  355. Routine Description:
  356. Processes property page.
  357. Arguments:
  358. None.
  359. Return Values:
  360. Returns true if processed successfully.
  361. --*/
  362. {
  363. if (!IsQuantityValid())
  364. return FALSE;
  365. NTSTATUS NtStatus = STATUS_SUCCESS;
  366. LLS_GROUP_INFO_1 MappingInfo1;
  367. //
  368. // Update information if necessary....
  369. //
  370. BeginWaitCursor(); // hourglass...
  371. if ((m_nLicenses != m_pMapping->GetInUse()) ||
  372. lstrcmp(MKSTR(m_strDescription), MKSTR(m_pMapping->m_strDescription)))
  373. {
  374. MappingInfo1.Name = MKSTR(m_strName);
  375. MappingInfo1.Comment = MKSTR(m_strDescription);
  376. MappingInfo1.Licenses = m_nLicenses;
  377. NtStatus = ::LlsGroupInfoSet(
  378. LlsGetActiveHandle(),
  379. MKSTR(m_strName),
  380. 1,
  381. (LPBYTE)&MappingInfo1
  382. );
  383. LlsSetLastStatus(NtStatus); // called api...
  384. *m_pUpdateHint |= NT_SUCCESS(NtStatus) ? UPDATE_GROUP_ALTERED : 0;
  385. }
  386. //
  387. // Delete specified users
  388. //
  389. while (NT_SUCCESS(NtStatus) && !m_deleteList.IsEmpty())
  390. {
  391. CUser* pUserDel = (CUser*)m_deleteList.RemoveHead();
  392. VALIDATE_OBJECT(pUserDel, CUser);
  393. NtStatus = ::LlsGroupUserDelete(
  394. LlsGetActiveHandle(),
  395. MKSTR(m_strName),
  396. MKSTR(pUserDel->m_strName)
  397. );
  398. pUserDel->InternalRelease(); // release now...
  399. if (NtStatus == STATUS_OBJECT_NAME_NOT_FOUND)
  400. NtStatus = STATUS_SUCCESS;
  401. LlsSetLastStatus(NtStatus); // called api...
  402. *m_pUpdateHint |= NT_SUCCESS(NtStatus) ? UPDATE_GROUP_ALTERED : 0;
  403. }
  404. CUser* pUserAdd;
  405. CMapping* pMapping;
  406. int iItem = -1;
  407. while (NT_SUCCESS(NtStatus) &&
  408. (NULL != (pUserAdd = (CUser*)::LvGetNextObj(&m_userList, &iItem, LVNI_ALL))))
  409. {
  410. VALIDATE_OBJECT(pUserAdd, CUser);
  411. //
  412. // Do not add users with this mapping as a parent
  413. //
  414. pMapping = (CMapping*)MKOBJ(pUserAdd->GetParent());
  415. if (NULL != pMapping)
  416. {
  417. ASSERT(m_pMapping == pMapping);
  418. pMapping->InternalRelease(); // just checking...
  419. }
  420. else
  421. {
  422. NtStatus = ::LlsGroupUserAdd(
  423. LlsGetActiveHandle(),
  424. MKSTR(m_strName),
  425. MKSTR(pUserAdd->m_strName)
  426. );
  427. LlsSetLastStatus(NtStatus); // called api...
  428. *m_pUpdateHint |= NT_SUCCESS(NtStatus) ? UPDATE_GROUP_ALTERED : 0;
  429. }
  430. }
  431. EndWaitCursor(); // hourglass...
  432. if (!NT_SUCCESS(NtStatus))
  433. {
  434. AbortPageIfNecessary(); // display error...
  435. return FALSE;
  436. }
  437. return TRUE;
  438. }
  439. BOOL CMappingPropertyPageSettings::OnCommand(WPARAM wParam, LPARAM lParam)
  440. /*++
  441. Routine Description:
  442. Message handler for WM_COMMAND.
  443. Arguments:
  444. wParam - message specific.
  445. lParam - message specific.
  446. Return Values:
  447. Returns true if message processed.
  448. --*/
  449. {
  450. if (wParam == ID_INIT_CTRLS)
  451. {
  452. if (!m_bAreCtrlsInitialized)
  453. {
  454. InitCtrls();
  455. if (!RefreshCtrls())
  456. {
  457. AbortPageIfNecessary(); // display error...
  458. }
  459. }
  460. ::SafeEnableWindow(
  461. &m_delBtn,
  462. &m_userList,
  463. CDialog::GetFocus(),
  464. m_userList.GetItemCount()
  465. );
  466. ::LvResizeColumns(&m_userList, &g_userColumnInfo);
  467. return TRUE; // processed...
  468. }
  469. return CDialog::OnCommand(wParam, lParam);
  470. }
  471. void CMappingPropertyPageSettings::OnDeltaPosSpin(NMHDR* pNMHDR, LRESULT* pResult)
  472. /*++
  473. Routine Description:
  474. Notification handler for UDN_DELTAPOS.
  475. Arguments:
  476. pNMHDR - notification header.
  477. pResult - return code.
  478. Return Values:
  479. None.
  480. --*/
  481. {
  482. UpdateData(TRUE); // get data
  483. ASSERT(NULL != pNMHDR);
  484. m_nLicenses += ((NM_UPDOWN*)pNMHDR)->iDelta;
  485. if (m_nLicenses < 0)
  486. {
  487. m_nLicenses = 0;
  488. ::MessageBeep(MB_OK);
  489. }
  490. else if (m_nLicenses > 999999)
  491. {
  492. m_nLicenses = 999999;
  493. ::MessageBeep(MB_OK);
  494. }
  495. UpdateData(FALSE); // set data
  496. ASSERT(NULL != pResult);
  497. *pResult = 1; // handle ourselves...
  498. }
  499. void CMappingPropertyPageSettings::OnUpdateQuantity()
  500. /*++
  501. Routine Description:
  502. Message handler for EN_UPDATE.
  503. Arguments:
  504. None.
  505. Return Values:
  506. None.
  507. --*/
  508. {
  509. long nLicensesOld = m_nLicenses;
  510. if (!IsQuantityValid())
  511. {
  512. m_nLicenses = nLicensesOld;
  513. UpdateData(FALSE);
  514. m_licEdit.SetFocus();
  515. m_licEdit.SetSel(0,-1);
  516. ::MessageBeep(MB_OK);
  517. }
  518. }
  519. BOOL CMappingPropertyPageSettings::IsQuantityValid()
  520. /*++
  521. Routine Description:
  522. Wrapper around UpdateData(TRUE).
  523. Arguments:
  524. None.
  525. Return Values:
  526. VT_BOOL.
  527. --*/
  528. {
  529. BOOL bIsValid;
  530. m_nLicensesMin = 1; // raise minimum...
  531. bIsValid = UpdateData(TRUE);
  532. m_nLicensesMin = 0; // reset minimum...
  533. return bIsValid;
  534. }
  535. void CMappingPropertyPageSettings::OnGetDispInfoUsers(NMHDR* pNMHDR, LRESULT* pResult)
  536. /*++
  537. Routine Description:
  538. Notification handler for LVN_GETDISPINFO.
  539. Arguments:
  540. pNMHDR - notification header.
  541. pResult - return code.
  542. Return Values:
  543. None.
  544. --*/
  545. {
  546. ASSERT(NULL != pNMHDR);
  547. LV_ITEM* plvItem = &((LV_DISPINFO*)pNMHDR)->item;
  548. ASSERT(plvItem);
  549. ASSERT(plvItem->iSubItem == 0);
  550. CUser* pUser = (CUser*)plvItem->lParam;
  551. VALIDATE_OBJECT(pUser, CUser);
  552. plvItem->iImage = BMPI_USER;
  553. lstrcpyn(plvItem->pszText, pUser->m_strName, plvItem->cchTextMax);
  554. ASSERT(NULL != pResult);
  555. *pResult = 0;
  556. }