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.

1017 lines
32 KiB

  1. // Copyright (c) 1997-1999 Microsoft Corporation
  2. // RootSecPage.cpp : implementation file
  3. //
  4. #include "precomp.h"
  5. #include "RootSecPage.h"
  6. #include "resource.h"
  7. #include "DataSrc.h"
  8. #include <cominit.h>
  9. #include "WMIHelp.h"
  10. const static DWORD rootSecPageHelpIDs[] = { // Context Help IDs
  11. IDC_SPP_PRINCIPALS, IDH_WMI_CTRL_SECURITY_NAMEBOX,
  12. IDC_SPP_ADD, IDH_WMI_CTRL_SECURITY_ADD_BUTTON,
  13. IDC_SPP_REMOVE, IDH_WMI_CTRL_SECURITY_REMOVE_BUTTON,
  14. IDC_SPP_ACCESS, IDH_WMI_CTRL_SECURITY_PERMISSIONSLIST,
  15. IDC_SPP_ALLOW, IDH_WMI_CTRL_SECURITY_PERMISSIONSLIST,
  16. IDC_SPP_PERMS, IDH_WMI_CTRL_SECURITY_PERMISSIONSLIST,
  17. 0, 0
  18. };
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CRootSecurityPage dialog
  21. CRootSecurityPage::CRootSecurityPage(CWbemServices &ns,
  22. CPrincipal::SecurityStyle secStyle,
  23. _bstr_t path, bool htmlSupport,
  24. int OSType) :
  25. CUIHelpers(ns, htmlSupport),
  26. m_secStyle(secStyle),
  27. m_path(path),
  28. m_OSType(OSType)
  29. {
  30. }
  31. //---------------------------------------------------------------------------
  32. #define MAX_COLUMN_CHARS 100
  33. void CRootSecurityPage::InitDlg(HWND hDlg)
  34. {
  35. m_hDlg = hDlg;
  36. HWND hPrinc = GetDlgItem(m_hDlg, IDC_SPP_PRINCIPALS);
  37. RECT rc;
  38. LV_COLUMN col;
  39. TCHAR szBuffer[MAX_COLUMN_CHARS] = {0};
  40. ListView_SetImageList(hPrinc,
  41. LoadImageList(_Module.GetModuleInstance(),
  42. MAKEINTRESOURCE(IDB_SID_ICONS)),
  43. LVSIL_SMALL);
  44. GetClientRect(hPrinc, &rc);
  45. LoadString(_Module.GetModuleInstance(), IDS_NAME, szBuffer, ARRAYSIZE(szBuffer));
  46. col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  47. col.fmt = LVCFMT_LEFT;
  48. col.pszText = szBuffer;
  49. col.iSubItem = 0;
  50. col.cx = rc.right;
  51. int x = ListView_InsertColumn(hPrinc, 0, &col);
  52. // pre-load the appropriate permissions.
  53. LoadPermissionList(hDlg);
  54. HRESULT hr = LoadSecurity(hDlg);
  55. if(m_OSType != OSTYPE_WINNT)
  56. {
  57. ::ShowWindow(::GetDlgItem(hDlg, IDC_MSG), SW_SHOWNA);
  58. }
  59. }
  60. //-----------------------------------------------------------------------------
  61. typedef struct {
  62. UINT ID;
  63. DWORD permBit;
  64. } PERM_DEF;
  65. PERM_DEF rootSecPerms[] =
  66. {
  67. {IDS_WBEM_GENERIC_EXECUTE, ACL_METHOD_EXECUTE},
  68. {IDS_WBEM_INSTANCE_WRITE, ACL_INSTANCE_WRITE},
  69. {IDS_WBEM_CLASS_WRITE, ACL_CLASS_WRITE},
  70. {IDS_WBEM_ENABLE, ACL_ENABLE},
  71. {IDS_WBEM_EDIT_SECURITY, ACL_WRITE_DAC}
  72. };
  73. PERM_DEF NSMethodPerms[] =
  74. {
  75. {IDS_WBEM_GENERIC_EXECUTE, ACL_METHOD_EXECUTE},
  76. {IDS_WBEM_FULL_WRITE, ACL_FULL_WRITE},
  77. {IDS_WBEM_PARTIAL_WRITE, ACL_PARTIAL_WRITE},
  78. {IDS_WBEM_PROVIDER_WRITE, ACL_PROVIDER_WRITE},
  79. {IDS_WBEM_ENABLE, ACL_ENABLE},
  80. {IDS_WBEM_REMOTE_ENABLE, ACL_REMOTE_ENABLE},
  81. {IDS_WBEM_READ_SECURITY, ACL_READ_CONTROL},
  82. {IDS_WBEM_EDIT_SECURITY, ACL_WRITE_DAC}
  83. };
  84. #define FULL_WRITE_IDX 1
  85. #define PARTIAL_WRITE_IDX 2
  86. #define PROVIDER_WRITE_IDX 3
  87. #define PERM_LABEL_SIZE 100
  88. void CRootSecurityPage::LoadPermissionList(HWND hDlg)
  89. {
  90. HWND hwndList = GetDlgItem(hDlg, IDC_SPP_PERMS); // checklist window
  91. HRESULT hr = S_OK;
  92. PERM_DEF *currRights = (m_secStyle == CPrincipal::RootSecStyle ?
  93. rootSecPerms :
  94. NSMethodPerms);
  95. int permCount = (m_secStyle == CPrincipal::RootSecStyle ? 5:8);
  96. TCHAR label[PERM_LABEL_SIZE] = {0};
  97. CPermission *permItem = NULL;
  98. for(int x = 0; x < permCount; x++)
  99. {
  100. UINT len = ::LoadString(_Module.GetModuleInstance(),
  101. currRights[x].ID, label, PERM_LABEL_SIZE);
  102. if(len != 0)
  103. {
  104. permItem = new CPermission;
  105. if(permItem == NULL)
  106. return;
  107. permItem->m_permBit = currRights[x].permBit;
  108. SendMessage(hwndList, CLM_ADDITEM, (WPARAM)label, (LPARAM)permItem);
  109. }
  110. }
  111. }
  112. //----------------------------------------------------------------
  113. HRESULT CRootSecurityPage::LoadSecurity(HWND hDlg)
  114. {
  115. HRESULT hr = WBEM_E_NOT_AVAILABLE; // bad IWbemServices ptr.
  116. HWND hPrinc = GetDlgItem(m_hDlg, IDC_SPP_PRINCIPALS);
  117. IWbemClassObject *inst = NULL; // NTLMUser instance when enumerating.
  118. if((bool)m_WbemServices)
  119. {
  120. int iItem;
  121. bool fPageModified = false;
  122. if(m_secStyle == CPrincipal::NS_MethodStyle) // M3
  123. {
  124. // call the method..
  125. CWbemClassObject _in;
  126. CWbemClassObject _out;
  127. hr = m_WbemServices.GetMethodSignatures("__SystemSecurity", "Get9XUserList",
  128. _in, _out);
  129. if(SUCCEEDED(hr))
  130. {
  131. hr = m_WbemServices.ExecMethod("__SystemSecurity", "Get9XUserList",
  132. _in, _out);
  133. if(SUCCEEDED(hr))
  134. {
  135. HRESULT hr1 = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
  136. if(FAILED(hr1))
  137. {
  138. hr = hr1;
  139. // and fall out.
  140. }
  141. else
  142. {
  143. _variant_t userList;
  144. HRESULT hr3 = _out.Get("ul", userList);
  145. if(SUCCEEDED(hr3))
  146. {
  147. hr3 = AddPrincipalsFromArray(hPrinc, userList);
  148. if(SUCCEEDED(hr3))
  149. {
  150. fPageModified = true;
  151. }
  152. else if(hr3 == WBEM_E_NOT_FOUND)
  153. {
  154. // no principals-- disable the checklist.
  155. EnableWindow(GetDlgItem(hDlg, IDC_SPP_PERMS), FALSE);
  156. EnableWindow(GetDlgItem(hDlg, IDC_SPP_REMOVE), FALSE);
  157. }
  158. else
  159. {
  160. hr = hr3;
  161. }
  162. }
  163. else
  164. {
  165. hr = hr3;
  166. }
  167. }
  168. }
  169. }
  170. }
  171. else //rootSecStyle M1
  172. {
  173. IEnumWbemClassObject *users = NULL;
  174. ULONG uReturned = 0;
  175. // NOTE: m_WbemServices better be the root\security ns.
  176. hr = m_WbemServices.CreateInstanceEnum(L"__NTLMUser", 0, &users);
  177. if(SUCCEEDED(hr))
  178. {
  179. // walk __NTLMUser
  180. while((SUCCEEDED(hr = users->Next(-1, 1, &inst, &uReturned))) &&
  181. (uReturned > 0))
  182. {
  183. CWbemClassObject princ(inst);
  184. fPageModified |= AddPrincipal(hPrinc, princ, CPrincipal::RootSecStyle, iItem);
  185. // release our copy.
  186. inst->Release();
  187. inst = NULL;
  188. } //endwhile
  189. // cleanup
  190. users->Release();
  191. }
  192. } //endif m_secStyle
  193. int count = ListView_GetItemCount(hPrinc);
  194. // no principals-- disable the checklist.
  195. EnableWindow(GetDlgItem(hDlg, IDC_SPP_PERMS), (count != 0? TRUE: FALSE));
  196. EnableWindow(GetDlgItem(hDlg, IDC_SPP_REMOVE), (count != 0? TRUE: FALSE));
  197. if(fPageModified)
  198. {
  199. PropSheet_Changed(GetParent(hDlg), hDlg);
  200. ListView_SetItemState(hPrinc, iItem, LVIS_SELECTED, LVIS_SELECTED);
  201. }
  202. } //endif (bool)m_WbemServices
  203. return hr;
  204. }
  205. //--------------------------------------------------------------------------
  206. HRESULT CRootSecurityPage::AddPrincipalsFromArray(HWND hPrinc,
  207. variant_t &vValue)
  208. {
  209. IUnknown *pVoid = NULL;
  210. SAFEARRAY* sa;
  211. HRESULT hr = E_FAIL;
  212. // if got a BYTE array back....
  213. if((vValue.vt & VT_ARRAY) &&
  214. (vValue.vt & VT_UNKNOWN))
  215. {
  216. // get it out.
  217. sa = V_ARRAY(&vValue);
  218. long lLowerBound = 0, lUpperBound = 0 ;
  219. SafeArrayGetLBound(sa, 1, &lLowerBound);
  220. SafeArrayGetUBound(sa, 1, &lUpperBound);
  221. if(lUpperBound != -1)
  222. {
  223. int iItem;
  224. long ix[1];
  225. for(long x = lLowerBound; x <= lUpperBound; x++)
  226. {
  227. ix[0] = x;
  228. hr = SafeArrayGetElement(sa, ix, &pVoid);
  229. if(SUCCEEDED(hr))
  230. {
  231. CWbemClassObject princ((IWbemClassObject *)pVoid);
  232. //load principals.
  233. iItem = x;
  234. AddPrincipal(hPrinc, princ, CPrincipal::NS_MethodStyle, iItem);
  235. }
  236. else
  237. {
  238. ATLASSERT(false);
  239. }
  240. }
  241. hr = S_OK;
  242. }
  243. else
  244. {
  245. hr = WBEM_E_NOT_FOUND;
  246. }
  247. }
  248. return hr;
  249. }
  250. //----------------------------------------------------------------
  251. bool CRootSecurityPage::AddPrincipal(HWND hPrinc,
  252. CWbemClassObject &princ,
  253. CPrincipal::SecurityStyle secStyle,
  254. int &iItem)
  255. {
  256. bool fPageModified = false;
  257. CPrincipal *pPrincipal = NULL;
  258. int idx = - 1;
  259. bstr_t name;
  260. name = princ.GetString("Authority");
  261. name += _T("\\");
  262. name += princ.GetString("Name");
  263. // if methodStyle security, its possible to get more than 1 ace
  264. // per user so see if the principal already exists.
  265. // NOTE: Otherwise the idx = -1 will force into the "new principal" code.
  266. if(secStyle == CPrincipal::NS_MethodStyle)
  267. {
  268. LVFINDINFO findInfo;
  269. findInfo.flags = LVFI_STRING;
  270. findInfo.psz = (LPCTSTR)name;
  271. idx = ListView_FindItem(hPrinc, -1, &findInfo);
  272. }
  273. // if not already there...
  274. if(idx == -1)
  275. {
  276. // addref when CPrincipal takes a copy.
  277. pPrincipal = new CPrincipal(princ, secStyle);
  278. LV_ITEM lvItem;
  279. // initialize the variable parts.
  280. lvItem.mask = LVIF_TEXT | LVIF_PARAM|LVIF_IMAGE;
  281. lvItem.iItem = iItem;
  282. lvItem.iSubItem = 0;
  283. lvItem.pszText = CloneString(name);
  284. if (lvItem.pszText)
  285. {
  286. lvItem.cchTextMax = _tcslen(lvItem.pszText);
  287. lvItem.iImage = pPrincipal->GetImageIndex();
  288. lvItem.lParam = (LPARAM)pPrincipal;
  289. lvItem.iIndent = 0;
  290. // Insert principal into list.
  291. if((iItem = ListView_InsertItem(hPrinc, &lvItem)) != -1)
  292. {
  293. ATLTRACE(_T("ListView_InsertItem %d\n"), iItem);
  294. fPageModified = TRUE;
  295. }
  296. }
  297. if (!fPageModified) // it failed
  298. {
  299. delete pPrincipal;
  300. pPrincipal = NULL;
  301. }
  302. }
  303. else // add it to the existing principal.
  304. {
  305. // get the existing principal instance.
  306. LVITEM item;
  307. item.mask = LVIF_PARAM;
  308. item.iItem = idx;
  309. item.iSubItem = 0;
  310. item.lParam = NULL;
  311. ListView_GetItem(hPrinc, &item);
  312. ATLTRACE(_T("extra ace\n"));
  313. pPrincipal = (CPrincipal *)item.lParam;
  314. // add the new ace to the existing principal.
  315. if(pPrincipal != NULL)
  316. {
  317. pPrincipal->AddAce(princ);
  318. } //endif pPrincipal
  319. }
  320. return fPageModified;
  321. }
  322. //----------------------------------------------------------------
  323. void CRootSecurityPage::OnApply(HWND hDlg, bool bClose)
  324. {
  325. CPrincipal *pPrincipal = NULL;
  326. VARIANT userList;
  327. SAFEARRAYBOUND rgsabound[1];
  328. SAFEARRAY *psa;
  329. CommitCurrent(hDlg);
  330. HWND hwndList = GetDlgItem(hDlg, IDC_SPP_PRINCIPALS);
  331. int count = ListView_GetItemCount(hwndList);
  332. LVITEM item;
  333. item.mask = LVIF_PARAM;
  334. // M3-9x will need an object array. Get ready.
  335. if(m_secStyle == CPrincipal::NS_MethodStyle)
  336. {
  337. VariantInit(&userList);
  338. rgsabound[0].lLbound = 0;
  339. rgsabound[0].cElements = count;
  340. psa = SafeArrayCreate(VT_UNKNOWN, 1, rgsabound);
  341. }
  342. // all principal, put their bits back into their instance.
  343. for(long i = 0; i < count; i++)
  344. {
  345. item.iItem = i;
  346. item.iSubItem = 0;
  347. item.lParam = NULL;
  348. ListView_GetItem(hwndList, &item);
  349. pPrincipal = (CPrincipal *)item.lParam;
  350. if(pPrincipal != NULL)
  351. {
  352. CWbemClassObject userInst;
  353. if(SUCCEEDED(pPrincipal->Put(m_WbemServices, userInst)))
  354. {
  355. // for M3-9x, also add it to an array of objects.
  356. if(m_secStyle == CPrincipal::NS_MethodStyle)
  357. {
  358. VARIANT v;
  359. VariantInit(&v);
  360. v.vt = VT_UNKNOWN;
  361. IWbemClassObject *pCO = userInst;
  362. v.punkVal = pCO;
  363. SafeArrayPutElement(psa, &i, pCO);
  364. }
  365. } //SUCCEEDED()
  366. } //endif pPrincipal
  367. } //endfor
  368. // M3-9x also needs an execMethod.
  369. if(m_secStyle == CPrincipal::NS_MethodStyle)
  370. {
  371. CWbemClassObject _in;
  372. CWbemClassObject _out;
  373. V_VT(&userList) = VT_UNKNOWN | VT_ARRAY;
  374. V_ARRAY(&userList) = psa;
  375. HRESULT hr = m_WbemServices.GetMethodSignatures("__SystemSecurity", "Set9XUserList",
  376. _in, _out);
  377. if(SUCCEEDED(hr))
  378. {
  379. hr = _in.Put("ul", userList);
  380. hr = m_WbemServices.ExecMethod("__SystemSecurity", "Set9XUserList",
  381. _in, _out);
  382. if(SUCCEEDED(hr))
  383. {
  384. HRESULT hr1 = HRESULT_FROM_NT(_out.GetLong("ReturnValue"));
  385. if(FAILED(hr1))
  386. {
  387. hr = hr1;
  388. }
  389. }
  390. VariantClear(&userList);
  391. }
  392. // HACK: because of how the core caches/uses security, I have to close &
  393. // reopen my connection because GetSecurity() will be immediately called
  394. // to refresh the UI. If I dont do this, GetSecurity() will return to old
  395. // security settings even though they're really saved.
  396. m_WbemServices.DisconnectServer();
  397. m_WbemServices.ConnectServer(m_path);
  398. } //endif NS_MethodStyle
  399. }
  400. //------------------------------------------------------------------------
  401. HRESULT CRootSecurityPage::ParseLogon(CHString1 &domUser,
  402. CHString1 &domain,
  403. CHString1 &user)
  404. {
  405. int slashPos = -1;
  406. int len = domUser.GetLength();
  407. for(int x = 0; x < len; x++)
  408. {
  409. if(domUser[x] == _T('\\'))
  410. {
  411. slashPos = x;
  412. break;
  413. }
  414. }
  415. // no slash??
  416. if(slashPos == -1)
  417. {
  418. // domain = _T('.');
  419. domain = _T(".");
  420. user = domUser;
  421. }
  422. else if(slashPos == 0) // leading slash...
  423. {
  424. // domain = _T('.');
  425. domain = _T(".");
  426. TCHAR *strTemp = (LPTSTR)(LPCTSTR)domUser;
  427. strTemp++;
  428. user = strTemp;
  429. // user = domUser[1];
  430. }
  431. else // domain\user
  432. {
  433. TCHAR buf[256] = {0}, buf2[256] = {0};
  434. domain = _tcsncpy(buf, domUser, slashPos);
  435. _tcscpy(buf, domUser);
  436. user = _tcscpy(buf2, &buf[slashPos+1]);
  437. }
  438. return S_OK;
  439. }
  440. //------------------------------------------------------------------------
  441. void CRootSecurityPage::OnAddPrincipal(HWND hDlg)
  442. {
  443. CHString1 domUser, domain, user;
  444. // Commit any outstanding bit changes.
  445. CommitCurrent(hDlg);
  446. // put up the user picker.
  447. if(GetUser(hDlg, domUser))
  448. {
  449. CWbemClassObject inst;
  450. HWND hwndList = GetDlgItem(hDlg, IDC_SPP_PRINCIPALS);
  451. ParseLogon(domUser, domain, user);
  452. // build default ace for the new guy.
  453. if(m_secStyle == CPrincipal::RootSecStyle)
  454. {
  455. inst = m_WbemServices.CreateInstance("__NTLMUser");
  456. inst.Put("Name", (bstr_t)user);
  457. inst.Put("Authority", (bstr_t)domain);
  458. inst.Put("EditSecurity", false);
  459. inst.Put("Enabled", true);
  460. inst.Put("ExecuteMethods", false);
  461. inst.Put("Permissions", (long)0);
  462. }
  463. else
  464. {
  465. inst = m_WbemServices.CreateInstance("__NTLMUser9x");
  466. inst.Put("Name", (bstr_t)user);
  467. inst.Put("Authority", (bstr_t)domain);
  468. inst.Put("Flags", (long)CONTAINER_INHERIT_ACE);
  469. inst.Put("Mask", (long)0);
  470. inst.Put("Type", (long)ACCESS_ALLOWED_ACE_TYPE);
  471. } //endif m_secStyle
  472. int iItem;
  473. if(AddPrincipal(hwndList, inst, m_secStyle, iItem))
  474. {
  475. EnableWindow(GetDlgItem(hDlg, IDC_SPP_PERMS), TRUE);
  476. // Tell the property sheet that we've changed.
  477. PropSheet_Changed(GetParent(hDlg), hDlg);
  478. }
  479. // if SOMETHING happened...
  480. if(iItem != -1)
  481. {
  482. // Select the already existing principal, or the last one inserted.
  483. ListView_SetItemState(hwndList, iItem, LVIS_SELECTED, LVIS_SELECTED);
  484. // NOTE: this should cause OnSelect() to be called to populate the
  485. // Permissions list.
  486. }
  487. int cItems = ListView_GetItemCount(hwndList);
  488. // no principals-- disable the checklist.
  489. EnableWindow(GetDlgItem(hDlg, IDC_SPP_PERMS), (cItems != 0? TRUE: FALSE));
  490. EnableWindow(GetDlgItem(hDlg, IDC_SPP_REMOVE), (cItems != 0? TRUE: FALSE));
  491. }
  492. }
  493. //------------------------------------------------------------------------
  494. bool CRootSecurityPage::GetUser(HWND hDlg, CHString1 &user)
  495. {
  496. TCHAR userName[100] = {0};
  497. bool retval = false;
  498. if(DisplayEditDlg(hDlg, IDS_USERPICKER_TITLE, IDS_USERPICKER_MSG,
  499. userName, 100) == IDOK)
  500. {
  501. user = CHString1(userName);
  502. retval = true;
  503. }
  504. return retval;
  505. }
  506. //------------------------------------------------------------------------
  507. void CRootSecurityPage::OnRemovePrincipal(HWND hDlg)
  508. {
  509. HWND hwndList;
  510. int iIndex;
  511. CPrincipal *pPrincipal;
  512. bool doit = false;
  513. hwndList = GetDlgItem(hDlg, IDC_SPP_PRINCIPALS);
  514. pPrincipal = GetSelectedPrincipal(hDlg, &iIndex);
  515. if(pPrincipal != NULL)
  516. {
  517. if(m_secStyle == CPrincipal::RootSecStyle)
  518. {
  519. CHString1 caption, msg;
  520. caption.LoadString(IDS_SHORT_NAME);
  521. msg.Format(MAKEINTRESOURCE(IDS_REMOVE_USER_FMT), pPrincipal->m_domain, pPrincipal->m_name);
  522. if(::MessageBox(hDlg, msg, caption,
  523. MB_YESNO|MB_DEFBUTTON2|MB_ICONEXCLAMATION) == IDYES)
  524. {
  525. pPrincipal->DeleteSelf(m_WbemServices);
  526. doit = true;
  527. }
  528. }
  529. else // MethodStyle can delete as expected.
  530. {
  531. doit = true;
  532. }// endif m_secStyle
  533. if(doit)
  534. {
  535. ListView_DeleteItem(hwndList, iIndex);
  536. // NOTE: LVN_DELETEITEM will cleanup the CPrincipal.
  537. // If we just removed the only item, move the focus to the Add button
  538. // (the Remove button will be disabled in LoadPermissionList).
  539. int cItems = ListView_GetItemCount(hwndList);
  540. if(cItems == 0)
  541. {
  542. SetFocus(GetDlgItem(hDlg, IDC_SPP_ADD));
  543. }
  544. else
  545. {
  546. // If we deleted the last one, select the previous one
  547. if(cItems <= iIndex)
  548. --iIndex;
  549. ListView_SetItemState(hwndList, iIndex, LVIS_SELECTED, LVIS_SELECTED);
  550. }
  551. // no principals-- disable the checklist.
  552. EnableWindow(GetDlgItem(hDlg, IDC_SPP_PERMS), (cItems != 0? TRUE: FALSE));
  553. EnableWindow(GetDlgItem(hDlg, IDC_SPP_REMOVE), (cItems != 0? TRUE: FALSE));
  554. PropSheet_Changed(GetParent(hDlg), hDlg);
  555. } //endif doit
  556. } // endif pPrincipal != NULL
  557. }
  558. //---------------------------------------------------------------------------------
  559. #define IDN_CHECKSELECTION 1 // this seems wierd.
  560. BOOL CRootSecurityPage::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  561. {
  562. switch(uMsg)
  563. {
  564. case WM_INITDIALOG:
  565. m_chkList.Attach(hDlg, IDC_SPP_PERMS);
  566. InitDlg(hDlg);
  567. break;
  568. case WM_NOTIFY:
  569. OnNotify(hDlg, wParam, (LPNMHDR)lParam);
  570. break;
  571. case WM_COMMAND:
  572. switch(LOWORD(wParam))
  573. {
  574. case IDC_SPP_ADD:
  575. if(HIWORD(wParam) == BN_CLICKED)
  576. OnAddPrincipal(m_hDlg);
  577. break;
  578. case IDC_SPP_REMOVE:
  579. if(HIWORD(wParam) == BN_CLICKED)
  580. OnRemovePrincipal(m_hDlg);
  581. break;
  582. // case IDC_SPP_ADVANCED:
  583. // if(HIWORD(wParam) == BN_CLICK)
  584. // OnAdvanced(m_hDlg);
  585. // break;
  586. case IDC_SPP_PRINCIPALS:
  587. if(HIWORD(wParam) == IDN_CHECKSELECTION)
  588. {
  589. // See if we have gotten a new selection. If not, then the
  590. // user must have clicked inside the listview but not on an item,
  591. // thus causing the listview to remove the selection. In that
  592. // case, disable the other controls.
  593. if(ListView_GetSelectedCount(GET_WM_COMMAND_HWND(wParam, lParam)) == 0)
  594. {
  595. EnablePrincipalControls(m_hDlg, FALSE);
  596. }
  597. }
  598. break;
  599. default: return FALSE; // Command not handled.
  600. }
  601. break;
  602. case WM_HELP:
  603. if (IsWindowEnabled(hDlg))
  604. {
  605. WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle,
  606. c_HelpFile,
  607. HELP_WM_HELP,
  608. (ULONG_PTR)rootSecPageHelpIDs);
  609. }
  610. break;
  611. case WM_CONTEXTMENU:
  612. if (IsWindowEnabled(hDlg))
  613. {
  614. WinHelp(hDlg, c_HelpFile,
  615. HELP_CONTEXTMENU,
  616. (ULONG_PTR)rootSecPageHelpIDs);
  617. }
  618. break;
  619. default:
  620. return FALSE;
  621. }
  622. return TRUE;
  623. }
  624. //-----------------------------------------------------------------------------
  625. BOOL CRootSecurityPage::OnNotify(HWND hDlg, WPARAM idCtrl, LPNMHDR pnmh)
  626. {
  627. LPNM_LISTVIEW pnmlv = (LPNM_LISTVIEW)pnmh;
  628. // Set default return value.
  629. SetWindowLongPtr(hDlg, DWLP_MSGRESULT, PSNRET_NOERROR);
  630. switch (pnmh->code)
  631. {
  632. case LVN_ITEMCHANGED:
  633. if(pnmlv->uChanged & LVIF_STATE)
  634. {
  635. // item *gaining* selection
  636. if((pnmlv->uNewState & LVIS_SELECTED) &&
  637. !(pnmlv->uOldState & LVIS_SELECTED))
  638. {
  639. // set bits based on principal.
  640. OnSelChange(hDlg);
  641. }
  642. // item *losing* selection
  643. else if(!(pnmlv->uNewState & LVIS_SELECTED) &&
  644. (pnmlv->uOldState & LVIS_SELECTED))
  645. {
  646. // put bits back into the principal.
  647. CommitCurrent(hDlg, pnmlv->iItem);
  648. // Post ourselves a message to check for a new selection later.
  649. // If we haven't gotten a new selection by the time we process
  650. // this message, then assume the user clicked inside the listview
  651. // but not on an item, thus causing the listview to remove the
  652. // selection. In that case, disable the combobox & Remove button.
  653. //
  654. // Do this via WM_COMMAND rather than WM_NOTIFY so we don't
  655. // have to allocate/free a NMHDR structure.
  656. PostMessage(hDlg, WM_COMMAND,
  657. GET_WM_COMMAND_MPS(pnmh->idFrom,
  658. pnmh->hwndFrom,
  659. IDN_CHECKSELECTION));
  660. }
  661. }
  662. break;
  663. case LVN_DELETEITEM:
  664. {
  665. // LPNMLISTVIEW pnmv = (LPNMLISTVIEW)pnmh;
  666. // int pIndex = pnmv->iItem;
  667. // CPrincipal *pPrincipal = GetSelectedPrincipal(hDlg, &pIndex);
  668. // delete pPrincipal;
  669. }
  670. break;
  671. case LVN_KEYDOWN:
  672. if(((LPNMLVKEYDOWN)pnmh)->wVKey == VK_DELETE)
  673. {
  674. OnRemovePrincipal(hDlg);
  675. }
  676. break;
  677. case CLN_CLICK:
  678. if(pnmh->idFrom == IDC_SPP_PERMS)
  679. {
  680. // ASSUMPTION: You wont see and disable change from this msg.
  681. PNM_CHECKLIST pnmc = (PNM_CHECKLIST)pnmh;
  682. CPermission *perm = (CPermission *)pnmc->dwItemData;
  683. int pIndex = pnmc->iItem;
  684. HWND hwndList = pnmc->hdr.hwndFrom;
  685. //HWND hPrinc = GetDlgItem(hDlg, IDC_SPP_PRINCIPALS);
  686. DWORD_PTR workingState = pnmc->dwState;
  687. // get the current principal.
  688. int cPrinc = -1;
  689. CPrincipal *pPrincipal = GetSelectedPrincipal(hDlg, &cPrinc);
  690. if(pPrincipal == NULL)
  691. break;
  692. HandleCheckList(hwndList, pPrincipal, perm, pnmc->iItem, &workingState);
  693. // if FULL_WRITE turned enabled & ON...
  694. // NOTE: if its DISABLED & ON, it must have been ENABLED & on before therefore
  695. // the partials would already be ENABLED & ON.
  696. if((perm->m_permBit == ACL_FULL_WRITE) &&
  697. (workingState == CLST_CHECKED))
  698. {
  699. CBL_SetState(hwndList, PARTIAL_WRITE_IDX, ALLOW_COL, CLST_CHECKED);
  700. CBL_SetState(hwndList, PROVIDER_WRITE_IDX, ALLOW_COL, CLST_CHECKED);
  701. }
  702. else if((perm->m_permBit == ACL_PARTIAL_WRITE) ||
  703. (perm->m_permBit == ACL_PROVIDER_WRITE))
  704. {
  705. // partials turned DISABLED & ON but FULL_WRITE inherits...
  706. if((workingState == CLST_CHECKDISABLED) &&
  707. (IS_BITSET(pPrincipal->m_inheritedPerms, ACL_FULL_WRITE)))
  708. {
  709. // turn FULL_WRITE DISABLED & ON.
  710. CBL_SetState(hwndList, FULL_WRITE_IDX, ALLOW_COL, CLST_CHECKDISABLED);
  711. }
  712. // if (ENABLED & OFF) or (DISABLED & ON without FULL_WRITE inherited)...
  713. else if(workingState != CLST_CHECKED)
  714. {
  715. // turn off FULL_WRITE.
  716. CBL_SetState(hwndList, FULL_WRITE_IDX, ALLOW_COL, CLST_UNCHECKED);
  717. }
  718. }
  719. PropSheet_Changed(GetParent(hDlg), hDlg);
  720. }
  721. break;
  722. case PSN_HELP:
  723. HTMLHelper(hDlg);
  724. break;
  725. case PSN_APPLY:
  726. OnApply(hDlg, (((LPPSHNOTIFY)pnmh)->lParam == 1));
  727. break;
  728. default:
  729. return FALSE;
  730. }
  731. return TRUE;
  732. }
  733. //-----------------------------------------------------------------------------
  734. void CRootSecurityPage::HandleCheckList(HWND hwndList,
  735. CPrincipal *pPrincipal,
  736. CPermission *perm,
  737. int iItem, DWORD_PTR *dwState)
  738. {
  739. // was ENABLED & ON, now turning OFF.
  740. if(*dwState == CLST_UNCHECKED)
  741. {
  742. // is there a inherited perm to shine through?
  743. if(IS_BITSET(pPrincipal->m_inheritedPerms, perm->m_permBit))
  744. {
  745. // yup, DISABLE & ON the checkbox.
  746. CBL_SetState(hwndList, iItem, ALLOW_COL, CLST_CHECKDISABLED);
  747. *dwState = CLST_CHECKDISABLED;
  748. }
  749. // else nothing extra to do.
  750. }
  751. // was DISABLED & ON, now turning OFF
  752. else if(*dwState == CLST_DISABLED)
  753. {
  754. // ENABLE & ON the checkbox.
  755. CBL_SetState(hwndList, iItem, ALLOW_COL, CLST_CHECKED);
  756. *dwState = CLST_CHECKED;
  757. }
  758. }
  759. //-----------------------------------------------------------------------------
  760. void CRootSecurityPage::OnSelChange(HWND hDlg)
  761. {
  762. BOOL bDisabled = FALSE; ///m_siObjectInfo.dwFlags & SI_READONLY;
  763. // If the principal list is empty or there is no selection, then we need
  764. // to disable all of the controls that operate on items in the listbox.
  765. // Get the selected principal.
  766. CPrincipal *pPrincipal = GetSelectedPrincipal(hDlg, NULL);
  767. if(pPrincipal)
  768. {
  769. HWND hwndList = GetDlgItem(hDlg, IDC_SPP_PERMS);
  770. // set it into the checklist.
  771. pPrincipal->LoadChecklist(hwndList, m_OSType);
  772. // Enable/disable the other controls.
  773. if(!bDisabled)
  774. {
  775. EnablePrincipalControls(hDlg, pPrincipal != NULL);
  776. }
  777. }
  778. }
  779. //-----------------------------------------------------------------------------
  780. void CRootSecurityPage::CommitCurrent(HWND hDlg, int iPrincipal /* = -1 */)
  781. {
  782. HWND hwndPrincipalList = GetDlgItem(hDlg, IDC_SPP_PRINCIPALS);
  783. HWND hwndPermList = GetDlgItem(hDlg, IDC_SPP_PERMS);
  784. // If an index isn't provided, get the index of the currently
  785. // selected principal.
  786. if(iPrincipal == -1)
  787. {
  788. iPrincipal = ListView_GetNextItem(hwndPrincipalList,
  789. -1, LVNI_SELECTED);
  790. }
  791. // if a principal is selected...
  792. if(iPrincipal != -1)
  793. {
  794. // Get the Principal from the selection.
  795. LV_ITEM lvItem;
  796. lvItem.mask = LVIF_PARAM;
  797. lvItem.iItem = iPrincipal;
  798. lvItem.iSubItem = 0;
  799. lvItem.lParam = 0;
  800. ListView_GetItem(hwndPrincipalList, &lvItem);
  801. CPrincipal *pPrincipal = (CPrincipal *)lvItem.lParam;
  802. if(pPrincipal != NULL)
  803. {
  804. // store the bit settings into the principal.
  805. pPrincipal->SaveChecklist(hwndPermList, m_OSType);
  806. } //end pPrincipal != NULL
  807. }
  808. }
  809. //-----------------------------------------------------------------------------
  810. void CRootSecurityPage::EnablePrincipalControls(HWND hDlg, BOOL fEnable)
  811. {
  812. EnableWindow(GetDlgItem(hDlg, IDC_SPP_PERMS), fEnable);
  813. if(!fEnable)
  814. {
  815. ShowWindow(GetDlgItem(hDlg, IDC_SPP_MORE_MSG), SW_HIDE);
  816. }
  817. EnableWindow(GetDlgItem(hDlg, IDC_SPP_REMOVE), fEnable);
  818. }
  819. //-----------------------------------------------------------------------------
  820. CPrincipal *CRootSecurityPage::GetSelectedPrincipal(HWND hDlg, int *pIndex)
  821. {
  822. HWND hListView = GetDlgItem(hDlg, IDC_SPP_PRINCIPALS);
  823. int iSelected = ListView_GetNextItem(hListView, -1, LVNI_SELECTED);
  824. if (iSelected == -1)
  825. return NULL;
  826. if (pIndex)
  827. *pIndex = iSelected;
  828. LV_ITEM lvi;
  829. lvi.mask = LVIF_PARAM;
  830. lvi.iItem = iSelected;
  831. lvi.iSubItem = 0;
  832. lvi.lParam = NULL;
  833. BOOL x = ListView_GetItem(hListView, &lvi);
  834. return (CPrincipal *)lvi.lParam;
  835. }
  836. //-------------------------------------------------------------------------------------
  837. HIMAGELIST CRootSecurityPage::LoadImageList(HINSTANCE hInstance, LPCTSTR pszBitmapID)
  838. {
  839. HIMAGELIST himl = NULL;
  840. HBITMAP hbm = LoadBitmap(hInstance, pszBitmapID);
  841. if (hbm != NULL)
  842. {
  843. BITMAP bm;
  844. GetObject(hbm, sizeof(bm), &bm);
  845. himl = ImageList_Create(bm.bmHeight, // height == width
  846. bm.bmHeight,
  847. ILC_COLOR | ILC_MASK,
  848. bm.bmWidth / bm.bmHeight,
  849. 0); // don't need to grow
  850. if (himl != NULL)
  851. ImageList_AddMasked(himl, hbm, CLR_DEFAULT);
  852. DeleteObject(hbm);
  853. }
  854. return himl;
  855. }